Search code examples
powershelltcp

Powershell Search for TCP connections by port


I wasn't able to find any posted code that would do something like a netstat in PowerShell and then search for established TCP connections by port.

I wrote the following function which works and was hoping for some feedback. Is there a simpler way? My company is still on Windows 7 so I can't use Get-NetTcpConnection.

<# Get-ESTConnectionByPort
Usage: Pass the port number to the function and it will return a boolian
value of true or false it will also echo an "Connected" or "Not Connected"
output to the console.
Get-ESTConnectionbyPort -Port "443"
#>
function Get-ESTConnectionByPort {
    Param($Port)

    $NetworkProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()

    $TcpConnections = $NetworkProperties.GetActiveTcpConnections()

    $TCPOut = $TcpConnections | Select-Object State, RemoteEndPoint

    $TCPTable = @($TCPOut.where({
        $_.RemoteEndPoint -match '.:' + $Port + '\z' -and
        $_.State -eq "Established"
    }))

    $Value = (-not $TCPTable)

    if (-not $Value) {
        Write-Host "Connected"
        $script:TCPConnected = $true
    } else {
        Write-Host "Not Connected"
        $script:TCPConnected = $false
    }

    $script:TCPConnected
}

Solution

  • this does the job in a slightly different way. it uses the .Where() and .ForEach() array methods for a slight speed-up. if you run PS2 or PS3, you will need to replace those with their pipeline versions [Where-Object & ForEach-Object].

    it allows multiple port numbers & multiple states to be chosen, then generates a [PSCusomtObject], sorts by the port, and finally outputs the objects. there are no other outputs.

    function Get-TcpConnectionInfo
        {
        <#
        Comment Based Help goes here
        #>
    
        [CmdletBinding ()]
        Param (
            [Parameter (
                Position = 0
                )]
                [int[]]
                $Port = 443,
    
            [Parameter (
                Position = 1
                )]
                [ValidateSet (
                    'Established',
                    'CloseWait',
                    'TimeWait'
                    )]
                [string[]]
                $State = 'Established'
            )
    
        begin {}
    
        process
            {
            $State = @($State).ForEach({$_.ToLower()})
    
            @([System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties().
                GetActiveTcpConnections()).
                Where({
                    # include only foreign RemoteEndPoint items
                    $_.LocalEndPoint.Address -ne $_.RemoteEndPoint.Address -and
                    $_.State.ToString().ToLower() -in $State -and
                    $_.RemoteEndPoint.Port -in $Port
                    }).
                ForEach({
                    [PSCustomObject]@{
                        State = $_.State
                        RemoteEndPoint = $_.RemoteEndPoint
                        }
                    }) |
                Sort-Object {$_.RemoteEndPoint.Port}
            }
    
        end {}
    
        } # end >> function Get-TcpConnectionInfo
    

    with the following call ...

    Get-TcpConnectionInfo -Port 443, 993 -State closewait, established
    

    ... it returns this ...

          State RemoteEndPoint    
          ----- --------------    
      CloseWait 13.33.115.238:443 
    Established 151.101.65.69:443 
    Established 198.252.206.25:443
    Established 23.194.113.80:443 
    Established 40.97.120.242:993 
    Established 173.194.70.108:993
    Established 173.194.70.108:993
    Established 40.97.120.242:993