Summary: Microsoft Scripting Guy, Ed Wilson, shows how to use Windows PowerShell to identify port connections in Windows 8.
Microsoft Scripting Guy, Ed Wilson, is here. There are only twenty-three days until Windows PowerShell Saturday in Charlotte, North Carolina. In fact, as far as I know, we have even had our last organizational meeting. The Scripting Wife has been busy finding water and soda on sale at various stores (shopping is one of her core skills), and the rest of the team has been busy working on sponsor layout drawings, presentations, and so on.
The Scripting Wife and I are heading to northern Kentucky where I will be teaching a Windows PowerShell class to a customer there. Teresa will be out and about visiting friends and going to outlet malls and finding cool places to eat. My good friend (and fellow Microsoftee), Robert from California, is flying in for the class, so we are looking forward to seeing him again. The Scripting Wife and I will be attending the first ever Cincinnati, Ohio Windows PowerShell User Group while we are in the area. I will be speaking about using Windows PowerShell 3.0 to manage a remote Windows 8 workstation. It’s a cool presentation if I do say so myself.
Identifying port connections
This is the third time I have written a script to obtain information about network connections. The first time I wrote it, I used a WMI class from the root/snmp namespace, and I wrote the script in VBScript. The second time, I used the NetStat command-line utility tool, I wrote it in Windows PowerShell 1.0, and I parsed the output by using regular expressions. In Windows PowerShell 3.0 in Windows 8, I use a simple cmdlet. This is a good thing, because gaining access to the SNMP namespace requires installing SNMP, and that requires evaluation and planning. I like things that are in the box as much as possible.
Using NetStat is easy (as long as you remember that it is netstat and not net statistics, and you remember what the switch –a –n –o accomplishes). The problem with netstat (it is not case sensitive) is that it returns string data instead of objects. Thus, the requirement for a bit of regular expression work. (I am not good enough with regular expressions to type very complicated patterns on the fly in front of a live audience without a lot of prior work—for example, say at Tech Mentor.)
As long as I do not need to do any post processing, and as long as I can remember the netstat –ano command (yes, you can gang the switches for netstat), there is no problem with the command. The output is shown here.
Using the Get-NetTCPConnection cmdlet
The default view of the Get-NetTCPConnection cmdlet is pretty useful, and it displays a decent amount of information about local and remote ports. For me, the display does not scale properly in my default Windows PowerShell size, but that is due to my need to take screenshots. On a larger monitor, using the default sizing for Windows PowerShell, the output is just fine. The image that follows illustrates the default output.
The nice thing about using the Get-NetTCPConnection cmdlet is that it returns objects, and it also has a number of useful switches. For example, if I am interested in only established connections, I use the state parameter, and I tell it to show established connections. The command is shown here.
Get-NetTCPConnection -State established
The command and the associated output are shown in the image that follows.
To view connections to the Internet, use the AppliedSetting parameter as shown here.
Get-NetTCPConnection -AppliedSetting internet
But keep in mind these are objects, and you can parse the information via Windows PowerShell. For example, I can quickly see the state of the connections on my computer by grouping by state. This command is shown here.
PS C:\> Get-NetTCPConnection | group state -NoElement
Count Name
----- ----
21 Listen
2 Established
I might be curious and want to see what ports are being utilized. I can easily see this by grouping by LocalPort as shown here.
PS C:\> Get-NetTCPConnection | group localport -NoElement | sort count -Descending
Count Name
----- ----
2 49199
2 49177
2 49155
2 49154
2 49153
2 49152
2 2179
2 135
1 47001
1 5985
1 445
1 62723
1 62613
1 62369
1 2559
1 139
After I have done this, I decide to obtain more information. Because these are objects, it is a simple matter of choosing the properties that I want to see. To find which properties are available, I first use the Get-Member cmdlet as shown here.
PS C:\> Get-NetTCPConnection | Get-Member -MemberType property | Format-Table name, definition -AutoSize
Name Definition
---- ----------
AggregationBehavior uint16 AggregationBehavior {get;set;}
AvailableRequestedStates uint16[] AvailableRequestedStates {get;set;}
Caption string Caption {get;set;}
CommunicationStatus uint16 CommunicationStatus {get;set;}
Description string Description {get;set;}
DetailedStatus uint16 DetailedStatus {get;set;}
Directionality uint16 Directionality {get;set;}
ElementName string ElementName {get;set;}
EnabledDefault uint16 EnabledDefault {get;set;}
EnabledState uint16 EnabledState {get;set;}
HealthState uint16 HealthState {get;set;}
InstallDate CimInstance#DateTime InstallDate {get;set;}
InstanceID string InstanceID {get;set;}
LocalAddress string LocalAddress {get;}
LocalPort uint16 LocalPort {get;}
Name string Name {get;set;}
OperatingStatus uint16 OperatingStatus {get;set;}
OperationalStatus uint16[] OperationalStatus {get;set;}
OtherEnabledState string OtherEnabledState {get;set;}
PrimaryStatus uint16 PrimaryStatus {get;set;}
PSComputerName string PSComputerName {get;}
RemoteAddress string RemoteAddress {get;}
RemotePort uint16 RemotePort {get;}
RequestedState uint16 RequestedState {get;set;}
Status string Status {get;set;}
StatusDescriptions string[] StatusDescriptions {get;set;}
TimeOfLastStateChange CimInstance#DateTime TimeOfLastStateChange {get;set;}
TransitioningToState uint16 TransitioningToState {get;set;}
I decide that I am interested in four specific properties, so I can write the command shown here.
Get-NetTCPConnection | ft state,localport, localaddress, remoteport, remoteaddress -AutoSize
The problem is that this is a lot of typing. I like to use wildcard characters in my Format-Table commands when I can get away with doing so. Here is a perfect situation for using wildcards and not destroying the readability of the command. Here is my revised command.
Get-NetTCPConnection | ft state,l*port, l*address, r*port, r*address –Auto
The command and the output are shown in the following image.
There is not an alias predefined for the Get-NetTCPConnection cmdlet. I found this by using the Get-Alias cmdlet as shown here.
Get-Alias -Definition Get-NetTCPConnection
If the Get-NetTCPConnection cmdlet is something that you intend to use a lot, you should create an alias for the cmdlet and store that alias in your profile. If you want to do so, you can even call it netstat. (I do not necessarily recommend this; I am simply showing you that you could do so. If you do something like that, and you want the real netstat, just call netstat.exe). This is shown here.
PS C:\> New-Alias -Name netstat -Value Get-NetTCPConnection
PS C:\> netstat -State established
LocalAddress LocalPort RemoteAddress RemotePort
------------ --------- ------------- --
192.168.0.47 62613 157.56.98.134 44
192.168.0.47 62369 157.56.98.129 44
Well, that is it for now. Join me tomorrow for more cool Windows PowerShell stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy