{"id":72761,"date":"2015-10-14T00:01:00","date_gmt":"2015-10-14T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/10\/14\/packet-sniffing-with-powershell-looking-at-messages\/"},"modified":"2019-02-18T09:34:54","modified_gmt":"2019-02-18T16:34:54","slug":"packet-sniffing-with-powershell-looking-at-messages","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/packet-sniffing-with-powershell-looking-at-messages\/","title":{"rendered":"Packet Sniffing with PowerShell: Looking at Messages"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Microsoft Scripting Guy Ed Wilson talks about looking at the message field in a packet log with Windows PowerShell.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Yesterday I begin analyzing a packet trace log.<\/p>\n<p align=\"left\" style=\"margin-left:30px\"><strong>Note<\/strong>&nbsp; For more information about setting up and making a packet trace, see <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/packet-sniffing-with-powershell-getting-started\/\" target=\"_blank\">Packet Sniffing with PowerShell: Getting Started<\/a>. For more information about doing basic analytics, see <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-parse-network-log\/\" target=\"_blank\">Use PowerShell to Parse Network Log<\/a>.<\/p>\n<p>You may be surprised if you have rebooted your computer, logged off and back on, and opened and closed Windows PowerShell. If you go to create a new net event session, and you call it session1 (like I did yesterday), you will get an error message today.<\/p>\n<p>How can that be? Well, obviously Windows PowerShell remembers what you did yesterday when you created the session in the first place. A big red error message appears stating that an object already exists. Well, duh. Obviously an object already exists or it would not be an object.<\/p>\n<p>That is a somewhat ambiguous error to say the least. True, but ambiguous. To clear up the matter, I need to use the <b>Remove-NetEventSession<\/b> cmdlet. The error message and the solution are shown in the following image:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-10-14-15-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-10-14-15-01.png\" alt=\"Image of error message\" title=\"Image of error message\" \/><\/a><\/p>\n<p>Now I have removed my error, so I can create the session anew, add <b>NetEventProvider<\/b>, and start the net event session:<\/p>\n<p style=\"margin-left:30px\">$session = New-NetEventSession -Name &quot;Session1&quot;<\/p>\n<p style=\"margin-left:30px\">Add-NetEventProvider -Name &quot;Microsoft-Windows-TCPIP&quot; -SessionName &quot;Session1<\/p>\n<p style=\"margin-left:30px\">Start-NetEventSession -Name &quot;Session1&quot;<\/p>\n<p>Now, I reproduce my problem, and then I stop my net event session:<\/p>\n<p style=\"margin-left:30px\">Stop-NetEventSession -Name session1<\/p>\n<p>I read the contents of the network trace log. I have to specify the <b>&ndash;Oldest<\/b> switch to avoid errors due to the way the log contents are read. This command is shown here:<\/p>\n<p style=\"margin-left:30px\">$log = Get-WinEvent -Path $session.LocalFilePath &ndash;Oldest<\/p>\n<p>The following image shows these commands and any associated output.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-10-14-15-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-10-14-15-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Now I want to see what timespan is documented by this trace, so I use <b>New-Timespan<\/b>:<\/p>\n<p style=\"margin-left:30px\">New-TimeSpan -end ($log | select -Last 1).timecreated -start ($log | select -first 1).Timecreated<\/p>\n<p>I can see that it covers 2 minutes and 15 seconds. This might be enough to document my problem. I also want to see how many entries I have. It turns out that I have over 11,000 entries:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $log.Count<\/p>\n<p style=\"margin-left:30px\">11328<\/p>\n<p>Sure is a good thing that Windows PowerShell is great at parsing log files!<\/p>\n<h2>Look at the Message field<\/h2>\n<p>In the trace log, the basic fields of the log are <b>TimeCreated<\/b>, <b>ID<\/b>, <b>LevelDisplayName<\/b>, and <b>Message<\/b>. The ID can be a great way to correlate events. But the <b>Message<\/b> field shows what is going on. To parse this message field, one can use <b>Select-String<\/b>.<\/p>\n<p style=\"margin-left:30px\"><b>Note&nbsp;<\/b> Luckily beginning with Windows PowerShell 3.0, PowerShell has what I call an automatic <b>foreach<\/b>&mdash;that is, it will automatically expand a collection of objects and allow me to examine a single property. This is a huge time saving feature, and one of my favorites. I wrote about it in <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/powershell-looping-the-automatic-foreach\/\" target=\"_blank\">PowerShell Looping: The Automatic Foreach<\/a>.<\/p>\n<p>All I need to do is access the message property from my collection of 11,000 events stored in the <b>$log<\/b> variable. I pipe the output to the <b>Select-String<\/b> cmdlet and do a simple match on the word <b>fail<\/b>. The command is shown here:<\/p>\n<p style=\"margin-left:30px\">$log.message | Select-String -SimpleMatch &#039;fail&#039;<\/p>\n<p>The output includes a lot of records. They tend to look like the following:<\/p>\n<p style=\"margin-left:30px\">TCP: connection 0xffffe000577e2430 (local=192.168.0.7:54083<\/p>\n<p style=\"margin-left:30px\">remote=127.0.0.1:443) connect attempt failed with status = {Device Timeout}<\/p>\n<p style=\"margin-left:30px\">The specified I\/O operation on %hs was not completed before the time-out period&nbsp;<span style=\"font-size:12px\">expired.<\/span><\/p>\n<p>It appears that there are different connection attempts that are failing with a timeout. Hmmm&hellip;how often is this happening? Well, I pipe the output to <b>Measure-Object<\/b> (<b>measure<\/b> is an alias):<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $log.message | Select-String -SimpleMatch &#039;fail&#039; | measure<\/p>\n<p style=\"margin-left:30px\">Count&nbsp;&nbsp;&nbsp; : 81<\/p>\n<p style=\"margin-left:30px\">Average&nbsp; :<\/p>\n<p style=\"margin-left:30px\">Sum&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"margin-left:30px\">Maximum&nbsp; :<\/p>\n<p style=\"margin-left:30px\">Minimum&nbsp; :<\/p>\n<p style=\"margin-left:30px\">Property :<\/p>\n<p>81 times in a 2 minute time frame. That sounds like it could be bad, and it would certainly explain the slowness of my computer. But what is it really? Well, I need to dive into the message field and see what is really connecting to what, and how many times the connections are failing.<\/p>\n<p>Before Windows PowerShell 5.0, this could have caused me some concern. I would have been falling back to write complicated REGEX patterns, and that would have taken some experimenting to get right. But with Windows PowerShell 5.0, I can parse this in no time at all because I have the <b>ConvertFrom-String<\/b> cmdlet. Here is the command I use:<\/p>\n<p style=\"margin-left:30px\">$log.message | Select-String -SimpleMatch &#039;fail&#039; | ConvertFrom-String<\/p>\n<p>The output that comes back is a collection of 27 fields. The default name is <b>p1 &ndash; p27<\/b>, but the doesn&#039;t matter because I see that I want P4 (my local IP address and port) and P5 (the remote IP address and port).<\/p>\n<p>As shown here, I also already know the connections are failing with a timeout because that is what I found earlier:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $log.message | Select-String -SimpleMatch &#039;fail&#039; | ConvertFrom-String<\/p>\n<p style=\"margin-left:30px\">P1&nbsp; : TCP:<\/p>\n<p style=\"margin-left:30px\">P2&nbsp; : connection<\/p>\n<p style=\"margin-left:30px\">P3&nbsp; : -35182904204240<\/p>\n<p style=\"margin-left:30px\">P4&nbsp; : (local=192.168.0.7:54083<\/p>\n<p style=\"margin-left:30px\">P5&nbsp; : remote=127.0.0.1:443)<\/p>\n<p style=\"margin-left:30px\">P6&nbsp; : connect<\/p>\n<p style=\"margin-left:30px\">P7&nbsp; : attempt<\/p>\n<p style=\"margin-left:30px\">P8&nbsp; : failed<\/p>\n<p style=\"margin-left:30px\">P9&nbsp; : with<\/p>\n<p style=\"margin-left:30px\">P10 : status<\/p>\n<p style=\"margin-left:30px\">P11 : =<\/p>\n<p style=\"margin-left:30px\">P12 : {Device<\/p>\n<p style=\"margin-left:30px\">P13 : Timeout}<\/p>\n<p style=\"margin-left:30px\">P14 : The<\/p>\n<p style=\"margin-left:30px\">P15 : specified<\/p>\n<p style=\"margin-left:30px\">P16 : I\/O<\/p>\n<p style=\"margin-left:30px\">P17 : operation<\/p>\n<p style=\"margin-left:30px\">P18 : on<\/p>\n<p style=\"margin-left:30px\">P19 : %hs<\/p>\n<p style=\"margin-left:30px\">P20 : was<\/p>\n<p style=\"margin-left:30px\">P21 : not<\/p>\n<p style=\"margin-left:30px\">P22 : completed<\/p>\n<p style=\"margin-left:30px\">P23 : before<\/p>\n<p style=\"margin-left:30px\">P24 : the<\/p>\n<p style=\"margin-left:30px\">P25 : time-out<\/p>\n<p style=\"margin-left:30px\">P26 : period<\/p>\n<p style=\"margin-left:30px\">P27 : expired..<\/p>\n<p style=\"margin-left:30px\">&lt;output truncated&gt;<\/p>\n<p>All I need to is select P4 and P5. This command is shown here:<\/p>\n<p style=\"margin-left:30px\">$log.message | Select-String -SimpleMatch &#039;fail&#039; | ConvertFrom-String | select p4, p5<\/p>\n<p>Here is the output now:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $log.message | Select-String -SimpleMatch &#039;fail&#039; | ConvertFrom-String | selec<\/p>\n<p style=\"margin-left:30px\">t p4, p5<\/p>\n<p style=\"margin-left:30px\">P4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P5<\/p>\n<p style=\"margin-left:30px\">&#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;<\/p>\n<p style=\"margin-left:30px\">(local=192.168.0.7:54083 remote=127.0.0.1:443)<\/p>\n<p style=\"margin-left:30px\">(local=192.168.0.7:54085 remote=127.0.0.2:443)<\/p>\n<p style=\"margin-left:30px\">&lt;output truncated&gt;<\/p>\n<p>I want to dive in and see where I am really having my problem. To do this, I want to group the output. This will show me the actual number of times each connection to each server is failing. The command I use is:<\/p>\n<p style=\"margin-left:30px\">$log.message | Select-String -SimpleMatch &#039;fail&#039; | ConvertFrom-String | select p4, p5 | group p5 | sort count &ndash;Descending<\/p>\n<p>Here is the output:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $log.message | Select-String -SimpleMatch &#039;fail&#039; | ConvertFrom-String | selec<\/p>\n<p style=\"margin-left:30px\">t p4, p5 | group p5 | sort count -Descending<\/p>\n<p style=\"margin-left:30px\">Count Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group<\/p>\n<p style=\"margin-left:30px\">&#8212;&#8211; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; 7 remote=127.0.0.1:80)&nbsp; {@{P4=(local=192.168.0.7:54228; P5=remote=127.0&#8230;.<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; 7 remote=127.0.0.2:&#8230; {@{P4=(local=192.168.0.7:54199; P5=remote=127.0&#8230;.<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; 6 remote=127.0.0.3:80)&nbsp; {@{P4=(local=192.168.0.7:54204; P5=remote=127.0&#8230;.<\/p>\n<p style=\"margin-left:30px\">&lt;output truncated&gt;<\/p>\n<p>That is all there is to using Windows PowerShell to parse a network trace log.&nbsp; Join me tomorrow when I will talk about more way cool stuff.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy Ed Wilson talks about looking at the message field in a packet log with Windows PowerShell. Microsoft Scripting Guy, Ed Wilson, is here. Yesterday I begin analyzing a packet trace log. Note&nbsp; For more information about setting up and making a packet trace, see Packet Sniffing with PowerShell: Getting Started. For [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[37,609,3,45],"class_list":["post-72761","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-networking","tag-powershell-5","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy Ed Wilson talks about looking at the message field in a packet log with Windows PowerShell. Microsoft Scripting Guy, Ed Wilson, is here. Yesterday I begin analyzing a packet trace log. Note&nbsp; For more information about setting up and making a packet trace, see Packet Sniffing with PowerShell: Getting Started. For [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/72761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=72761"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/72761\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=72761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=72761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=72761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}