Technical: Microsoft – Windows – Networking – Netstat – Code Snippet in Powershell

Technical: Microsoft – Windows – Networking – Netstat – Code Snippet in Powershell

 

Background

A day or so ago I noticed that I was using way too much network ports.  Thankfully,  was able to use the netstat.exe binary that is bundled with the OS and deduct that my problem was too many DNS Connections.

My trek is posted @ Technical: Microsoft – DNS – Network Port Allocation ( https://danieladeniji.wordpress.com/2014/05/15/technical-microsoft-dns-network-port-usage/).

 

Introduction

But, I thought it was a bit cumbersome to slice the data in interesting ways.

I hoped that I could find Cmdlets/API for doing so in Powershell.  But, no go!

Yes, I can go down the same path as my old IBM OS/2 Ehlappi days, basically screen scraping.  And, use Regular Expression to parse the lines read in.

But, who wants to try that these days of lazy programmers.

And, so upon finding ” Vasily Gusev & Richard Mueller – How to Convert Text Output of a Legacy Console Application to PowerShell Objects ( http://social.technet.microsoft.com/wiki/contents/articles/4244.how-to-convert-text-output-of-a-legacy-console-application-to-powershell-objects.aspx ) “, I knew I had stumbled on a nice well.

 

 Code

 

#REQUIRES -Version 2.0
Param(
		  [switch]$detail
		, [string]$groupBy
	  )


<#  
.SYNOPSIS
    Netstat in PowerShell
.DESCRIPTION
    A little Netstat script in powershell.
	Supports both detailed and summary view.
.NOTES
    File Name      : netstat.ps1  
    Author         : Daniel Adeniji
    Prerequisite   : PowerShell V2 over Vista and upper.
    Copyright 2014 Daniel Adeniji
.LINK
    Script posted over:  
    http://danieladeniji.github.com


.PARAMETER detail
  Detail is a boolean
   Options are $true, $false


.PARAMETER groupBy
  When not in detail play and in summary view
    Options are ProcessName, PortState, LocalAddress, LocalPort, RemoteAddress, RemotePort


.EXAMPLE
    powershell ./netstat.ps1 -detail:$false

.EXAMPLE
    powershell ./netstat.ps1 -detail:$true

.EXAMPLE
	powershell ./netstat.ps1 -groupBy:RemotePort

#>

#Get ProcessList
$processList = Get-Process

function isNumeric ($x) {
    try {
        0 + $x | Out-Null
        return $true
    } catch {
        return $false
    }
}


function parseIPAddressPortIPV6
{
	<#
.SYNOPSIS
	  parse function; enhanced to support IPV6

.DESCRIPTION
	  parse function; enhanced to support IPV6

.EXAMPLE
	  parseIPAddressPortIPV6 $LocalAddressIPPort ([REF]$LocalAddressIP) ([REF]$LocalAddressPort )


.PARAMETER IPAddressPort
	    The IP Address Combination

.PARAMETER IPAddress
	   The IP Address.  Please pass reference as will be returned by function

.PARAMETER IPPort
	   The IP Port.  Please pass reference as will be returned by function

  #>
  
	param(    [string]$IPAddressPort
		, [ref]$IPAddress
		, [ref]$IPPort	
             )

	# get string length		
	$iStringLen = $IPAddressPort.Length
			
	# reverse string			
	#$IPAddressPortReversed = stringReverse($IPAddressPort)

	# find colon in string
	$iPosOfColonInString = $IPAddressPort.LastIndexOf(":")

	# if colon found
	if ($iPosOfColonInString -gt 0)
	{
	
		$IPAddress.Value = $IPAddressPort.Substring(0, $iPosOfColonInString)
			
		$IPPort.Value = $IPAddressPort.Substring($iPosOfColonInString+1, $iStringLen -$iPosOfColonInString -1)
	
	}
	else
	{
	
		$IPAddress.Value = ""
		$IPPort.Value = ""

	}
	

}

function get-NetStats
{

	#issue netstat
	$netstatOutput = netstat -a -n -o 
	
	
	$iNumberofOutputLines = $netstatOutput.length
	
	# remove first 4 lines
	$netstatOutput = $netstatOutput[4..$iNumberofOutputLines]	
	
	
	$netstatOutput | foreach {
			
			
		$LocalAddressIP = $null
		$LocalAddressPort = "LP" #$null
		$LocalAddressIPPortArray = $null
		$iLocalAddressIPPortArrayLength = 0	

		$RemoteAddressIP = $null
		$RemoteAddressPort = "RP" #$null	
		$RemoteAddressIPPortArray = $null
		$iRemoteAddressIPPortArrayLength = 0
		
		# get current line	
		$LineContents = $_
			
		# remove leading spaces
		$LineContentsPertinent = $LineContents.TrimStart()
			
		# based on spaces break line down into columns
		$connectionLineColumn = $LineContentsPertinent -split "\s+", 5
		
		$Protocol = $connectionLineColumn[0]
		
		$LocalAddressIPPort = $connectionLineColumn[1]
		$RemoteAddressIPPort = $connectionLineColumn[2]	
		
			
		# Adjust for missing PortState when port is not yet in use
		if (isNumeric($connectionLineColumn[3]) -eq $true)
		{
			$PortState = ""
			$ProcessPID = $connectionLineColumn[3]								
		}
		else
		{
			$PortState = $connectionLineColumn[3]
			$ProcessPID = $connectionLineColumn[4]								
		}			

		
		if ($LocalAddressIPPort)
		{
			parseIPAddressPortIPV6 $LocalAddressIPPort ([REF]$LocalAddressIP) ([REF]$LocalAddressPort )
        }

		
		if ($RemoteAddressIPPort)
		{
			parseIPAddressPortIPV6 $RemoteAddressIPPort ([REF]$RemoteAddressIP) ([REF]$RemoteAddressPort )
        }

		
		#get list of Processes that match our Port ID
		$procMatch = $processList | Where-Object -FilterScript {$_.Id -eq $ProcessPID} 
			
		#get process name that matches port
		ForEach ($Process in $procMatch)
		{
			$processName = $procMatch.Name	
		}
			
		# Convert raw data into an object
		New-Object -Type PSObject -Property @{
			
			Protocol = $Protocol
			
			LocalAddressIPPort = $LocalAddressIPPort
			LocalAddressIP = $LocalAddressIP		
			LocalAddressPort = $LocalAddressPort	
			
			RemoteAddressIPPort = $RemoteAddressIPPort	
			RemoteAddressIP = $RemoteAddressIP	
			RemoteAddressPort = $RemoteAddressPort
			
			PortState = $PortState
				
			ProcessPID = $ProcessPID
				
			ProcessName = $processName
				
			}

	}	# foreach 	
	

}	

#If detailed view, then show data
if ($detail -eq $true)
{
	Get-NetStats | Sort ProcessName | Format-Table Protocol, LocalAddressIPPort, LocalAddressIP, RemoteAddressIPPort, PortState, ProcessName -AutoSize
}
#else show summary data
else
{

	if ($groupBy -eq "PortState")
	{
		Get-NetStats | Group-Object -Property PortState | Sort Name | Format-Table Name, Count -AutoSize
	}
	elseif ($groupBy -eq "LocalAddress")
	{
		Get-NetStats | Group-Object -Property LocalAddressIP | Sort Name | Format-Table Name, Count -AutoSize
	}
	elseif ($groupBy -eq "LocalPort")
	{
		Get-NetStats | Group-Object -Property LocalAddressPort | Sort Name | Format-Table Name, Count -AutoSize
	}	
	elseif ($groupBy -eq "RemoteAddress")
	{
		Get-NetStats | Group-Object -Property RemoteAddressIP | Sort Name | Format-Table Name, Count -AutoSize

	}	
	
	elseif ($groupBy -eq "RemotePort")
	{
		Get-NetStats | Group-Object -Property RemoteAddressPort | Sort Name | Format-Table Name, Count -AutoSize

	}
	
	else
	{
		Get-NetStats | Group-Object -Property ProcessName | Sort Count -desc| Format-Table Name, Count -AutoSize
	}
	
}

 

 

Invocation


 Example

 powershell ./netstat.ps1 -detail:$false

Output:

netstatps--summary

 

Example

 powershell ./netstat.ps1 -detail:$true

Output:

netstatps--detailed

 

Repository

GitHub

The little Powershell applet is publicly available @ https://github.com/DanielAdeniji/NetstatPS.

 

Credits

Code Beautifier

Crediting hilite.me ( http://hilite.me/ )

 

References

Powershell

Powershell – Text To PowerShell Object

 

Powershell – Netstat

 

Powershell – Process

Powershell – Group Object

 

Powershell – Function

 

Powershell – Pass by reference

 

Powershell – parameters

Powershell – Is String numeric?

 

Powershell – Split

 

Powershell – Comments

 

Powershell – Errors

 

 

 

 

 

 

 

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s