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
}