Summary: Ed Wilson, Microsoft Scripting Guy, talks about using Windows PowerShell to parse a network trace log.
Microsoft Scripting Guy, Ed Wilson, is here. Today I want to talk a little bit about using Windows PowerShell to parse a network trace log. In yesterday’s blog post, Packet Sniffing with PowerShell: Getting Started, I talked using Windows PowerShell to do a network trace.
Yesterday, I created a network trace log. I can use that log, or I can create a new log.
Note These commands require that Windows PowerShell is elevated.
When I create a new NetEvent session with the New-NetEventSession cmdlet, it returns a NetEvent session object:
PS C:\> New-NetEventSession -Name “Session1”
Name : Session1
CaptureMode : SaveToFile
LocalFilePath : C:\Windows\system32\config\systemprofile\AppData\Local\NetEvent
Trace.etl
MaxFileSize : 250 MB
TraceBufferSize : 0 KB
MaxNumberOfBuffers : 0
SessionStatus : NotRunning
This object contains the path to the log file. I like to store the results in a variable so that I can easily access the log file without having to do a lot of typing. This is shown here:
PS C:\> $session = New-NetEventSession -Name “Session1”
PS C:\> $session.LocalFilePath
C:\Windows\system32\config\systemprofile\AppData\Local\NetEventTrace.etl
After I add my event provider and start the session, I can begin the logging, as shown here:
PS C:\> Add-NetEventProvider -Name “Microsoft-Windows-TCPIP” -SessionName “Session1”
Name : Microsoft-Windows-TCPIP
SessionName : Session1
Level : 4
MatchAnyKeyword : 0xFFFFFFFFFFFFFFFF
MatchAllKeyword : 0x0
PS C:\> Start-NetEventSession -Name “Session1”
After doing the trace, I stop the session:
Stop-NetEventSession -Name session1
Examine the trace log
Now I use the Get-WinEvent cmdlet to examine the trace log. To do this, I like to read the contents into a variable so I can parse it. This is where storing the path to the log comes in handy. Here is the command:
$log = Get-WinEvent -Path $session.LocalFilePath –Oldest
Note The trace log must be read in reverse order, so the –Oldest switch is required. Otherwise, an error occurs.
I can inspect the first record by indexing into the collection:
PS C:\> $log[0]
ProviderName: Microsoft-Windows-TCPIP
TimeCreated Id LevelDisplayName Message
———– — —————- ——-
10/12/2015 3:22:06 PM 1300 Information TCP: connection 0xffffe001cc3…
But it becomes more interesting to look at event IDs or to try to parse the message block. For example, I can look at the message block by accessing the Message property:
PS C:\> $log[0].Message
TCP: connection 0xffffe001cc33cd10 (local=192.168.0.7:52259 remote=127.0.0.1:443) exists. State = CloseWaitState. PID = 2640.
Here, I look at a specific ID:
PS C:\> $log.Where({$_.id -eq 1348})
ProviderName: Microsoft-Windows-TCPIP
TimeCreated Id LevelDisplayName Message
———– — —————- ——-
10/12/2015 3:23:00 PM 1348 Information TCP: CTCP DataTransferTimeout…
10/12/2015 3:23:00 PM 1348 Information TCP: CTCP DataTransferTimeout…
10/12/2015 3:23:00 PM 1348 Information TCP: CTCP DataTransferTimeout…
10/12/2015 3:23:00 PM 1348 Information TCP: CTCP DataTransferTimeout…
10/12/2015 3:23:01 PM 1348 Information TCP: CTCP DataTransferTimeout…
<output truncated>
How many of those events were there? I can find that out by the count:
PS C:\> $log.Where({$_.id -eq 1348}).count
72
As shown here, I can sort by ID and do a count:
PS C:\> $log | group id -NoElement | sort count -Descending
Count Name
—– —-
1188 1074
649 1332
628 1157
364 1156
359 1158
196 1159
189 1229
189 1331
137 1051
72 1187
72 1351
72 1079
72 1348
68 1193
52 1086
40 1300
<output truncated>
Well, is an ID 1074 a good thing or a bad thing? I can easily find out by looking at a sample event, and then examining the message string:
PS C:\> $log.Where({$_.id -eq 1074})[0]
ProviderName: Microsoft-Windows-TCPIP
TimeCreated   ; Id LevelDisplayName Message
———– — —————- ——-
10/12/2015 3:22:08 PM 1074 Information TCP: connection 0xffffe001d35…
PS C:\> $log.Where({$_.id -eq 1074})[0].message
TCP: connection 0xffffe001d3537c00: Received data with number of bytes = 186. ThSeq
= 2458887771.
PS C:\>
If I am not sure as to what time frame I am working with, I can look at the first and last events in my log:
PS C:\> $log | select -Last 1
ProviderName: Microsoft-Windows-TCPIP
TimeCreated Id LevelDisplayName Message
———– — —————- ——-
10/12/2015 3:24:15 PM 1193 Information TCP: endpoint/connection 0xff…
PS C:\> $log | select -First 1
ProviderName: Microsoft-Windows-TCPIP
TimeCreated Id LevelDisplayName Message
———– — —————- ——-
10/12/2015 3:22:06 PM 1300 Information TCP: connection 0xffffe001cc3…
So, it looks like only a couple minutes. To know for sure, I can create a new timespan that represents the amount of log time:
PS C:\> New-TimeSpan -end ($log | select -Last 1).timecreated -start ($log | select -first 1).Timecreated
Days : 0
Hours : 0
Minutes : 2
Seconds : 9
Milliseconds : 628
Ticks : 1296282580
TotalDays : 0.00150032706018519
TotalHours : 0.0360078494444444
TotalMinutes : 2.16047096666667
TotalSeconds : 129.628258
TotalMilliseconds : 129628.258
That is all there is to using Windows PowerShell to parse a network log. Join me tomorrow when I will talk about more cool 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
0 comments