Get-Packet

A few days ago I blogged about packet sniffer PowerShell script. Needless to say I was intrigued and spent some time dissecting to better understand it. Don’t worry, no PowerShell scripts were harmed during this operation. This is a nifty piece of PowerShell coding. Of course I’m never one to leave well enough alone so I had to add a few touches which I hope the original author doesn’t mind. You can download my version here

First, the original script kept running unless you pressed Ctrl-C.  I made some slight modifications so that the script could end more gracefully.

$ESCkey  = 27
Write-Host "Press the ESC key to stop sniffing" -foregroundcolor "CYAN"
$Running=$true
While ($Running)
 {
 
  if ($host.ui.RawUi.KeyAvailable) {
         $key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp,IncludeKeyDown")
            if ($key.VirtualKeyCode -eq $ESCkey) {
             $Running=$False
            }
      }

The main packet sniffing code is within the While loop. It will run until the Esc key is pressed. The ReadKey() method detects key strokes and if the VirtualKeyCode property equals the value for the Esc key, $Running is set to $False and the script will end. This makes it much easier to save output to a variable:

PS C:\$sniff=c:\scripts\get-packet.ps1

I also added a timestamp property to the custom object so I could do time-related analysis later.

$obj | Add-Member noteproperty Time (Get-Date)

This property lets me do tasks like this which displays packet information with a timestamp value that includes milliseconds

PS C:\>$sniff [0..100] | Select @{Name="timeStamp";Expression={(new-timespan $_.time).ToString() }},Source,Destination,Protocol,*Port

timeStamp   : 21:32:18.2082876
Source      : 207.46.236.102
Destination : 172.16.10.102
Protocol    : TCP
DestPort    : 50392
SourcePort  : 21

timeStamp   : 21:32:18.1892849
Source      : 207.46.236.102
Destination : 172.16.10.102
Protocol    : TCP
DestPort    : 50392
SourcePort  : 21

timeStamp   : 21:32:18.1642815
Source      : 207.46.236.102
Destination : 172.16.10.102
Protocol    : TCP
DestPort    : 50395
SourcePort  : 20

I also made some slight changes to the original code for creating the custom object which is probably just a personal preference since the original worked just fine. The original was written as one long pipelined expression.  Personally I found it harder to troubleshoot.

Once I’ve saved my trace to a variable, here are some things I can do with it. Depending on how long your trace ran, this variable could be quite large.

PS C:\> $sniff | sort protocol | group protocol | format-table Count,Name -autosize

Count Name
—– —-
   42 ICMP
   17 IGMP
6496 TCP
  163 UDP

PS C:\> $sniff | sort SourcePort | group SourcePort | sort count -descending |
>> Select -first 5 | format-table Count,Name -autosize
>>

Count Name
—- —-
5747 80
401 143
113 23
  93 53
  59 0

If you have suggestions for enhancements or improvements, I’d love to hear them. Stay tuned to the blog as well.  I have an addition to this script that I think you’ll find interesting, at least I hope so.

 

While ($Running)
    {
     if ($host.ui.RawUi.KeyAvailable) {
         $key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp,IncludeKeyDown")
            if ($key.VirtualKeyCode -eq $ESCkey) {
             $Running=$False
            }
      }