Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Get Your TCP Ports Here!

Posted on July 29, 2010

Once again, the PowerShell forum at ScriptingAnswers.com has undone me. I was answering a question about running Netstat in a PowerShell session on a remote computer which got me thinking about a PowerShell function to turn NETSTAT.EXE output into objects. Once you have an object then you can do all sorts of things.  Needless to say I got hooked on working something up instead of working on what I had planned for the day. The good news is that you get a tool and there's still a few hours of the day left for me to get something else accomplished. I'm sure there are plenty of variations on this topic already out there, but here's my contribution: Get-TCP.
[cc lang="Powershell"]
Function Get-TCP {
<# .Synopsis Get TCP Netstat information .Description This function calls the command line NETSTAT.EXE tool and returns an object representation of the TCP data. Protocol   : TCP Localhost  : 172.16.10.127 LocalPort  : 49259 RemoteHost : 74.201.86.29 RemotePort : https Status     : ESTABLISHED The default is the local computer without name resolution. However you can specify a remote computername, assuming the remote computer is running PowerShell 2.0 and has remoting enabled. Use -ResolveHost to resolve IP addresses to host names. This is a little slower. This function will only return IPv4 hosts and addresses .Parameter Computername The name of the computer to query. The default is the localhost. .Parameter ResolveHost Resolve IP addresses to host names. This is a little slower. The is the equivalent of running Netstat.exe without any parameters. .Parameter ResolvePort Resolve the service name associated with the port. This requires access to the legacy Services file found at $env:windir\system32\drivers\etc\services. .Parameter IncludeRaw Include the raw netstat data. .Example PS C:\> get-tcp Return TCP Netstat information for the local computer. .Example PS C:\> get-tcp "Server1","Server2" -resolve

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

Return TCP Netstat information for computers Server1 and Server2 with resolved IP addresses.
.Example
PS C:\> get-content computers.txt } get-tcp -resolveHost | where {$_.RemotePort -eq 80} | format-table -autosize

Get HTTP connections for every computer in computers.txt and present as a formatted table.
.Example
PS C:\> get-tcp | sort RemotePort | Select RemotePort -unique

Get a sorted list of all remote connections by port.
.Inputs
Strings
.Outputs
Custom object
.Link
https://jdhitsolutions.com/blog

.Link
Invoke-Command

.Notes
NAME:      Get-TCP
VERSION:   1.5
AUTHOR:    Jeffery Hicks
LASTEDIT:  July 29, 2010

Learn more with a copy of Windows PowerShell 2.0: TFM (SAPIEN Press 2010)

#>

[cmdletbinding()]

Param(
[Parameter(Position=0,ValueFromPipeline=$True)]
[string[]]$Computername=$env:computername,
[switch]$ResolveHost,
[switch]$ResolvePort,
[switch]$IncludeRaw
)

Begin {
Write-Verbose "Starting $($myinvocation.mycommand)"
if ($ResolveHost) { Write-Verbose "Resolving host names"}
if ($ResolvePort) {Write-Verbose "Resolving port names"}
#put everything into a script block so that if the computer
#is remote it can be executed using Invoke-Command
$scriptblock={netstat.exe -n | where {$_.Contains("TCP") -AND $_ -notmatch "\["}}

Write-Verbose "Caching Services information"
$file="$env:windir\system32\drivers\etc\services"
#get just tcp services
$services=Get-Content -Path $file | Select-String -Pattern "/tcp"

Write-Verbose $($scriptblock.ToString())

#define the name resolution function
Function Resolve-DNS  {

[cmdletbinding()]

Param(
[Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True,
HelpMessage="Enter an IP Address to resolve")]
[string[]]$Address
)
Begin {
Write-Verbose "Starting Resolve-DNS"
#turn off error pipeline
$errorActionPreference="SilentlyContinue"
}
Process {
foreach ($IP in $Address) {
Write-Verbose "Resolving $IP"
$dns=[System.net.DNS]::GetHostByAddress("$IP")
if (-not $dns) {
Write-Verbose "no record found for $IP"
$h=$IP
$a=$null
}
else {
$h=$dns.hostname
$a=$dns.AddressList
}
New-Object -TypeName PSobject -Property @{
Hostname=$h
Addresses=$a
}
} #foreach
} #process

End {
#turn On error pipeline
$errorActionPreference="Continue"
}
} #end function

} #begin

Process {
foreach ($computer in $computername) {
Write-Verbose "Getting raw NETSTAT data from $($computer.toUpper())"
if ($computer -eq $env:computername) {
#just run the script block if local computer
$data=&$scriptblock
}
else {
Try {
$data=Invoke-Command -ScriptBlock $scriptblock -computername $computer -errorAction "Stop"
}
Catch {
Write-Warning "Failed to run command on $computer"
Write-Warning $error[0].exception.message
}
} #else
#process data
Write-Verbose "Returned $($data.count) items"
Write-Verbose "Parsing data"
#initialize a hash table for IP names
$hash=@{}
foreach ($tcp in $data) {
Write-Verbose $tcp.trim()
#split the line removing empty spaces
$arr=$tcp.trim().split() | where {$_}
$localData=$arr[1].Split(":")
$remoteData=$arr[2].Split(":")
$protocol=$arr[0]
$raw=$tcp.trim()
$local=$localData[0]
[int]$localPort=$localData[1]
$remote=$remoteData[0]
[int]$remotePort=$remoteData[1]
$status=$arr[3]

#if resolve host requested build a dictionary or
#ip addresses so we don't need to resolve one already resolved
#and change the property value accordingly
if ($resolveHost) {
if ($hash.contains("$local")) {
$local=$hash.Item("$local")
}
else {
#look up name
Write-Verbose "Resolving $local"
$localLookup=Resolve-DNS "$local"
#add to hash
$hash.Add("$local",$localLookup.Hostname)
#update property
$local=$localLookup.Hostname
}
#do the same for remote
if ($hash.contains("$remote")) {
$remote=$hash.Item("$remote")
}
else {
#look up name
Write-Verbose "Resolving $remote"
$remoteLookup=Resolve-DNS "$remote"
#add to hash
$hash.Add("$remote",$localLookup.Hostname)
#update property
$remote=$RemoteLookup.Hostname
}
} #if $resolveHost

#resolve ports if specified
if ($resolvePort) {
#this is a mini scriptblock to return the service name
#in lieu of a full-blown function
$getsvc={Param ([string]$port)
Write-Verbose "searching for $port"
$service=$services | Select-String -pattern  "\s$port/tcp"

if ($service) {
$data=$service.ToString().Trim().split() | where {$_}
Write-Output $data[0]
}
else {
Write-Output $port
}

} #end $getSvc

[string]$localPort=&$getsvc $localPort
[string]$remotePort=&$getsvc $remotePort

} #end resolveport

#create a new object and pipe it to Select-Object so that
#the properties are in a nice order
$obj=New-Object -TypeName "PSObject" -Property @{
Protocol=$protocol
Localhost=$local
LocalPort=$localPort
RemoteHost=$remote
RemotePort=$remotePort
Status=$status
}
if ($IncludeRaw) {
$obj | Add-Member -MemberType "Noteproperty" -Name "Raw" -Value $raw -PassThru |
Select-Object -Property Protocol,LocalHost,LocalPort,RemoteHost,RemotePort,Status,Raw
}
else {
$obj | Select-Object -Property Protocol,LocalHost,LocalPort,RemoteHost,RemotePort,Status
}
} #foreach $tcp
} #foreach computer
} #Process

End {
Write-Verbose "Ending $($myinvocation.mycommand)"
}

} #end function[/cc]
This is an advanced Windows PowerShell 2.0 function. By default it converts output from Netstat -n to object. I've parsed the output so you get an object like this for each line.

[cc lang=DOS]
Protocol   : TCP
Localhost  : 172.16.10.122
LocalPort  : 60553
RemoteHost : 74.201.86.29
RemotePort : 443
Status     : ESTABLISHED[/cc]

When you run Netstat without any parameters it resolves both host and port names. I've separated the two so you can use either -ResolveHost and/or -ResolvePort. The former uses an embedded function to get the host entry name by IP address. If not found, then the IP address is used. This function by the way only returns IPv4 information. Service ports are resolved by finding the associated TCP port in the legacy Services file. What you end up with is something like this:

The function can also accept a remote computername as it uses Invoke-Command to run the Netstat command remotely.  All the results are then processed locally. You can pipe computernames to the function or it accepts arrays.

If you have any questions on the nitty-gritty details, please post a comment.

Download Get-TCP.ps1.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

2 thoughts on “Get Your TCP Ports Here!”

  1. Jeffery Hicks says:
    July 29, 2010 at 3:26 pm

    Formatting the code in the blog entry is a little wonky. The file you download and run is properly formatted.

  2. Jeffery Hicks says:
    July 29, 2010 at 6:31 pm

    You can tell I’m not a developer. I didn’t even think about the .NET classes which will also return this type of information.

    $properties=[System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
    $udp=$properties.GetActiveUdpListeners()
    $tcp=$properties.GetActiveTcpConnections()

    Thanks to JVierra for pointing this out.

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d