Get Detailed Network Connection Information

Standard

This function will list all connections to a Windows computer in PowerShell. While most admins are familiar with Netstat and unless you have Windows 8.1 or Server 2012 R2 there’s no PowerShell equivalent. There’s a .Net method that could be utilized but it doesn’t supply the process identifier (PID) to relate that connection the process using it. Alternatively you create a custom type that uses IP Helper that does have the PID but that’s unnecessarily complicated for what I want. Instead I opted for parsing Netstat’s string output into a format I could use. Additionally I added in DNS lookup for remote addresses, process details from Get-Process, and several parameters to get just what you want.

Download Get-Connections PowerShell script

EXAMPLE:

#Note that using -Lookup will take additional time for reverse lookup to complete
Get-Connections -Lookup -Protocol TCP
#OR
Get-Connections -Established
#OR
Get-Connection -RemotePort 80

CODE:

function Get-Connections
{
param(
 [Parameter(Position=0,Mandatory=$false)][switch]$Lookup,
 [Parameter(Position=1,Mandatory=$false)][ValidateSet('TCP','UDP')][string]$Protocol,
 [Parameter(Position=2,Mandatory=$false)][ValidateSet('Closed','Close_Wait','Closing','Delete_Tcb','DeleteTcb','Established','Fin_Wait_1','Fin_Wait_2','Last_Ack','Listening','Syn_Received','Syn_Sent','Time_Wait','Unknown')][string]$State,
 [Parameter(Position=3,Mandatory=$false)][string]$Remote,
 [Parameter(Position=4,Mandatory=$false)][string]$Process,
 [Parameter(Position=5,Mandatory=$false)][int]$RemotePort,
 [Parameter(Position=6,Mandatory=$false)][int]$LocalPort
)
$Processes = Get-Process | select Name,Path,Description,Company,Product,ProductVersion,Responding,ID
$Netstat = netstat -ano | Select-String -Pattern '\s+(TCP|UDP)'
$DNS = [System.Net.Dns]
$Computer = "$env:computername.$env:userdnsdomain"
$Results = @()

if($Protocol -ne "UDP"){
$TCP = $Netstat | Select-String -Pattern 'TCP'
foreach ($item in $TCP){
 $Link = $item -split " " | where {$_.length -gt 0}
 #Split up the address and port text
 $PortLocal = $Link[1] -split ":" | select -Last 1 | where {$_ -match '[0-65535]'}
 $LocalAddress = ($Link[1] -split ":" | select -First (($Link[1] -split ":").Count-1)) -join ":"
 $PortRemote = $Link[2] -split ":" | select -Last 1 | where {$_ -match '[0-65535]'}
 $RemoteAddress = ($Link[2] -split ":" | select -First (($Link[2] -split ":").Count-1)) -join ":"
 #Map get-process to Netstat PID
 $App = $Processes | where {$_.ID -eq $Link[4]}
 #If lookup flag was used try to get DNS name for remote address
 if($Lookup -and $RemoteAddress.Length -gt 6){try{$DNSName = $DNS::GetHostEntry($RemoteAddress)}catch{$DNSName=$null}}else{$DNSName=$null}
 #Add properties to array
 $obj = New-Object PSObject
 $obj | Add-Member -MemberType NoteProperty -Name "Local Name" -Value $Computer
 $obj | Add-Member -MemberType NoteProperty -Name "Local Address" -Value $LocalAddress
 $obj | Add-Member -MemberType NoteProperty -Name "Local Port" -Value $PortLocal
 $obj | Add-Member -MemberType NoteProperty -Name "Remote Address" -Value $RemoteAddress
 $obj | Add-Member -MemberType NoteProperty -Name "Remote Port" -Value $PortRemote
 if($Lookup){$obj | Add-Member -MemberType NoteProperty -Name "Remote Name" -Value $DNSName.HostName}
 $obj | Add-Member -MemberType NoteProperty -Name "Net Protocol" -Value $Link[0]
 $obj | Add-Member -MemberType NoteProperty -Name "Net State" -Value $Link[3]
 $obj | Add-Member -MemberType NoteProperty -Name "Process ID" -Value $Link[4]
 $obj | Add-Member -MemberType NoteProperty -Name "Process Name" -Value $App.Name
 $obj | Add-Member -MemberType NoteProperty -Name "Process Path" -Value $App.Path
 $obj | Add-Member -MemberType NoteProperty -Name "Process Description" -Value $App.Description
 $obj | Add-Member -MemberType NoteProperty -Name "Process Company" -Value $App.Company
 $obj | Add-Member -MemberType NoteProperty -Name "Process Product" -Value $App.Product
 $obj | Add-Member -MemberType NoteProperty -Name "Process Version" -Value $App.ProductVersion
 $obj | Add-Member -MemberType NoteProperty -Name "Process Responding" -Value $App.Responding
 $Results += $obj
}}
#UDP is parsed seperately since it's stateless and therefore one less column after the split
if($Protocol -ne "TCP"){
$UDP = $Netstat | Select-String -Pattern 'UDP'
foreach ($item in $UDP){
 $Link = $item -split " " | where {$_.length -gt 0}
 #Split up the address and port text
 $PortLocal = $Link[1] -split ":" | select -Last 1 | where {$_ -match '[0-65535]'}
 $LocalAddress = ($Link[1] -split ":" | select -First (($Link[1] -split ":").Count-1)) -join ":"
 $PortRemote = $Link[2] -split ":" | select -Last 1 | where {$_ -match '[0-65535]'}
 $RemoteAddress = ($Link[2] -split ":" | select -First (($Link[2] -split ":").Count-1)) -join ":"
 #Map get-process to Netstat PID
 $App = $Processes | where {$_.ID -eq $Link[3]}
 #Add properties to array
 $obj = New-Object PSObject
 $obj | Add-Member -MemberType NoteProperty -Name "Local Name" -Value $Computer
 $obj | Add-Member -MemberType NoteProperty -Name "Local Address" -Value $LocalAddress
 $obj | Add-Member -MemberType NoteProperty -Name "Local Port" -Value $PortLocal
 if($Protocol -ne "UDP"){#If UDP is selected these columns aren't needed
 $obj | Add-Member -MemberType NoteProperty -Name "Remote Address" -Value $RemoteAddress
 $obj | Add-Member -MemberType NoteProperty -Name "Remote Port" -Value $PortRemote
 if($Lookup){$obj | Add-Member -MemberType NoteProperty -Name "Remote Name" -Value $null}
 $obj | Add-Member -MemberType NoteProperty -Name "Net Protocol" -Value $Link[0]
 $obj | Add-Member -MemberType NoteProperty -Name "Net State" -Value $null}
 $obj | Add-Member -MemberType NoteProperty -Name "Process ID" -Value $Link[3]
 $obj | Add-Member -MemberType NoteProperty -Name "Process Name" -Value $App.Name
 $obj | Add-Member -MemberType NoteProperty -Name "Process Path" -Value $App.Path
 $obj | Add-Member -MemberType NoteProperty -Name "Process Description" -Value $App.Description
 $obj | Add-Member -MemberType NoteProperty -Name "Process Company" -Value $App.Company
 $obj | Add-Member -MemberType NoteProperty -Name "Process Product" -Value $App.Product
 $obj | Add-Member -MemberType NoteProperty -Name "Process Version" -Value $App.ProductVersion
 $obj | Add-Member -MemberType NoteProperty -Name "Process Responding" -Value $App.Responding
 $Results += $obj
}}
#Filtering results if parameters specified
if($Remote){$Results = $Results | Where {$_.'Remote Address' -match $Remote}}
if($Process){$Results = $Results | Where {$_.'Process Name' -match $Process}}
if($State){$Results = $Results | Where {$_.'Net State' -match $State}}
if($RemotePort){$Results = $Results | Where {$_.'Remote Port' -match $RemotePort}}
if($LocalPort){$Results = $Results | Where {$_.'Local Port' -match $LocalPort}}

Return $Results
}

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.