If you’ve been trying out the Get-Packet script you’ve seen that there is a great deal of information. I wanted an easy way to analyze the data so I put together a script called Analyze-Packet that will slice and dice a saved network trace and produce a summary report.
1: Param([object]$sniff)
2:
3: $activity="Analyzing network trace"
4: Write-Progress -Activity $activity -status "Counting packets" -percentcomplete 1
5: $count = "Total packet count: {0}" -f $sniff.count
6:
7: Write-Progress -Activity $activity -status "Calculating elapsed time" -percentcomplete 5
8: $elapsed = "Total elapsed time: {0}" -f ($sniff[-1].time -$sniff[0].time).ToString()
9: #calculate packets per second
10: $pps = $sniff.count/(($sniff[-1].time -$sniff[0].time).totalseconds)
11: $pps="{0:N4}" -f $pps
12: $packetsPerSecond="Packets per second: $pps"
13:
14: Write-Progress -Activity $activity -status "Calculating protocol distribution" -percentcomplete 20
15: $protocols = $sniff | sort protocol | group protocol | sort count -descending | select Count,@{name="Protocol";Expression={$_.name}}
16:
17: Write-Progress -Activity $activity -status "Building source list" -percentcomplete 30
18: $sourcelist = $sniff | sort source | select Source
19:
20: Write-Progress -Activity $activity -status "Calculating source distribution" -percentcomplete 35
21: $ips = $sourcelist| group source |sort count -descending | select Count,Name
22:
23: $sources=@()
24:
25: #turn off errors to prevent the script from halting if an IP can't be resolved
26: $errorActionPreference="SilentlyContinue"
27:
28: for ($i=0;$i -lt $ips.count;$i++) {
29: Write-Progress -Activity $activity -status "Resolving Source IP addresses" -currentoperation $ips[$i].name -percentcomplete (($i/$ips.count)*100)
30:
31: $obj=New-Object PSObject
32: $resolved=[system.Net.dns]::getHostEntry($ips[$i].Name).hostName
33:
34: if (!$resolved) {
35: $resolved="Not Found"
36: }
37: $obj | Add-Member -MemberType Noteproperty -name "Count" -value $ips[$i].Count
38: $obj | Add-Member -MemberType Noteproperty -name "IP" -value $ips[$i].name
39: $obj | Add-Member -MemberType Noteproperty -name "Host" -value $resolved
40: $sources+=$obj
41: }
42:
43: #turn error pipeline back on
44: $errorActionPreference="Continue"
45:
46: Write-Progress -Activity $activity -status "Calculating source port distribution" -percentcomplete 40
47: $sourceport = $sniff | sort sourceport | group sourceport |sort count -descending | select Count,@{name="Port";Expression={$_.name}}
48:
49: Write-Progress -Activity $activity -status "Calculating destination distribution" -percentcomplete 50
50: $destinations = $sniff | sort destination | group destination | sort count -descending | select Count,@{name="IP";Expression={$_.name}}
51:
52: Write-Progress -Activity $activity -status "Calculating destination port distribution" -percentcomplete 60
53: $destinationport = $sniff | sort destport | group destport |sort count -descending | select Count,@{name="Port";Expression={$_.name}}
54:
55: Write-Progress -Activity $activity -status "Presenting data" -Completed $True -percentcomplete 100
56:
57: #write results
58: write "NETWORK TRACE ANALYSIS"
59: write ("-" * 50)
60: write `t
61: write $count
62: write $elapsed
63: write $packetsPerSecond
64: write `t
65: write "PROTOCOLS"
66: $protocols | Select Count,Protocol,@{Name="Percentage";Expression={"{0:P4}" -f ($_.count/$sniff.count)}}
67: write "DESTINATION IP"
68: $destinations | Select Count,IP,@{Name="Percentage";Expression={"{0:P4}" -f ($_.count/$sniff.count)}}
69: write "DESTINATION PORTS"
70: $destinationport | select Count,Port,@{Name="Percentage";Expression={"{0:P4}" -f ($_.count/$sniff.count)}}
71: write "SOURCE IP"
72: $sources | Select Count,IP,Host,@{Name="Percentage";Expression={"{0:P4}" -f ($_.count/$sniff.count)}}
73: write "SOURCE PORTS"
74: $sourceport | Select Count,Port,@{Name="Percentage";Expression={"{0:P4}" -f ($_.count/$sniff.count)}}
75:
The script takes a variable that holds the results of the Get-Packet script. I tried to come up with as many different views of the data as I could think of that might be relevant. There are break downs of packets by source ports, IP addresses and more. Because the analysis takes time, I used Write-Progress to provide feedback. This is a great cmdlet to use for long running tasks like this. Something else you might find useful from the script is code I use to resolve IP addresses to a host name using the System.Net.DNS class.
1: $resolved=[system.Net.dns]::getHostEntry($ips[$i].Name).hostName
I turned off the error pipeline because if the method failed to resolved an IP address, it produced an error that halted the script.
I recommend saving the results to a variable since this script may take several minutes or longer run depending on the size of your trace.
PS C:\> $report=c:\scripts\Analyze-packet.ps1 $sniff
Here’s a truncated sample of a report to give you an idea of what to expect. You could pipe $report to Out-File or Out-Printer. However, because it doesn’t output a single object it doesn’t lend itself to exporting or converting to an HTML file. I might come back to this at a later date and see if there are any alternatives. If you have suggestions, please let me know.
“Now I’ll just ‘have’ to buy the book !”
Thanx J
A.