<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://powershell.com/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results for 'app:weblogs' matching tags 'guest blogger' and 'messaging and communication'</title><link>http://powershell.com/cs/search/SearchResults.aspx?q=app:weblogs&amp;tag=guest+blogger,messaging+and+communication&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tags 'guest blogger' and 'messaging and communication'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>Get Exchange Online Mailbox Size in GB</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/02/27/get-exchange-online-mailbox-size-in-gb.aspx</link><pubDate>Wed, 27 Feb 2013 06:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:21841</guid><dc:creator>Anonymous</dc:creator><description>&lt;p align="left"&gt;&lt;strong&gt;Summary&lt;/strong&gt;: Microsoft PFE, Brian Jackett, talks about using Windows PowerShell to get Exchange Online Mailbox size in GB.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Today I want to welcome back guest blogger, Brian T. Jackett.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Brian T. Jackett is a premier field engineer at Microsoft who has specialized in SharePoint development, Project Server, and Windows PowerShell for over four years. Brian is a steering committee member of the Buckeye SharePoint User Group, and he enjoys giving back to the community through giving presentations, planning and volunteering at conferences, maintaining a SharePoint/.NET-centric blog, and contributing to the SharePoint Twitterverse. He also holds several Microsoft Certified Technology Specialist (MCTS) certifications for SharePoint-related technologies. &lt;br /&gt;Brian&amp;rsquo;s blog: &lt;a href="http://www.briantjackett.com/" target="_blank"&gt;The Frog Pond of Technology&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, here&amp;rsquo;s Brian&amp;hellip;&lt;/p&gt;
&lt;p&gt;Office 365 is picking up in deployments and user adoption. Windows PowerShell is one tool for the administration of Office 365 that is similar to its on-premises counterparts, but it can have a few differences. In this post, I will discuss one way to get the size of an Exchange Online mailbox in bytes and consequently GBs.&lt;/p&gt;
&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;Getting the size of an on-premises Exchange 2010 mailbox is fairly easy. In his blog &lt;a href="http://blogs.technet.com/b/gary/archive/2010/02/20/the-get-mailboxstatistics-cmdlet-the-totalitemsize-property-and-that-pesky-little-b.aspx" target="_blank"&gt;The Get-MailboxStatistics Cmdlet, the TotalitemSize Property, and that pesky little &amp;ldquo;b&amp;rdquo;&lt;/a&gt;, &amp;nbsp;fellow PFE &lt;a href="http://blogs.technet.com/gary" target="_blank"&gt;Gary Siepser&lt;/a&gt;, explains how to accomplish this task by using the mailbox &lt;strong&gt;TotalItemSize&lt;/strong&gt; property with methods such as ToMB() and ToGB(). Note that Gary&amp;rsquo;s script will not work when remoting from a local machine that doesn&amp;rsquo;t have the Exchange object model installed or loaded.&lt;/p&gt;
&lt;p&gt;A similar type of scenario exists if you are executing Windows PowerShell against Exchange Online. The data type for &lt;strong&gt;TotalItemSize&lt;/strong&gt; being returned (&lt;strong&gt;ByteQuantifiedSize&lt;/strong&gt;) exists in the Exchange namespace. If the WindowsPowerShell session doesn&amp;rsquo;t have access to that namespace (or hasn&amp;rsquo;t loaded it), Windows PowerShell works with an approximation of that data type.&lt;/p&gt;
&lt;p&gt;The following script is a sample on the TechNet article&amp;nbsp;&lt;a href="http://technet.microsoft.com/en-us/exchangelabshelp/gg576861#ViewAllMailboxes" target="_blank"&gt;View Mailbox Sizes and Mailbox Quotas Using Windows PowerShell&lt;/a&gt;, which a customer of mine tried, but it was failing. (I made minor edits to fit it on page and remove references to deleted item size.)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Mailbox -ResultSize Unlimited |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;Get-MailboxStatistics |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;Select DisplayName,StorageLimitStatus, `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;@{name=&amp;quot;TotalItemSize (MB)&amp;quot;; expression={[math]::Round( `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;($_.TotalItemSize.Split(&amp;quot;(&amp;quot;)[1].Split(&amp;quot; &amp;quot;)[0].Replace(&amp;quot;,&amp;quot;,&amp;quot;&amp;quot;)/1MB),2)}}, `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;ItemCount |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;Sort &amp;quot;TotalItemSize (MB)&amp;quot; -Descending&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3343.hsg_2D00_2_2D00_27_2D00_13_2D00_1.jpg"&gt;&lt;img title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3343.hsg_2D00_2_2D00_27_2D00_13_2D00_1.jpg" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The script is targeted to Exchange 2010, but it fails for Exchange Online. In Exchange Online, when referencing the &lt;strong&gt;TotalItemSize&lt;/strong&gt; property, there is not a &lt;strong&gt;Split&lt;/strong&gt; method, which ultimately causes the script to return no data for &lt;strong&gt;&amp;ldquo;Total Item Size (MB)&amp;rdquo;&lt;/strong&gt; column.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;A simple solution would be to add a call to the &lt;strong&gt;ToString&lt;/strong&gt; method off of the &lt;strong&gt;TotalItemSize&lt;/strong&gt; property (shown in bold on line 5 in the following script).&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Mailbox -ResultSize Unlimited |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;Get-MailboxStatistics |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;Select DisplayName,StorageLimitStatus, `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;@{name=&amp;quot;TotalItemSize (MB)&amp;quot;; expression={[math]::Round( `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;($_.TotalItemSize.&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;ToString()&lt;/span&gt;&lt;/strong&gt;.Split(&amp;quot;(&amp;quot;)[1].Split(&amp;quot; &amp;quot;)[0].Replace(&amp;quot;,&amp;quot;,&amp;quot;&amp;quot;)/1MB),2)}}, `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;ItemCount |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;Sort &amp;quot;TotalItemSize (MB)&amp;quot; -Descending |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;Export-CSV &amp;quot;C:\My Documents\All Mailboxes.csv&amp;quot; -NoTypeInformation&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8561.hsg_2D00_2_2D00_27_2D00_13_2D00_2.jpg"&gt;&lt;img title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8561.hsg_2D00_2_2D00_27_2D00_13_2D00_2.jpg" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This fixes the script to run but the numerous string replacements and splits are an eyesore to me. I attempted to simplify the string manipulation with a regular expression. (For more information about regular expressions in Windows PowerShell, see the &lt;a href="http://www.regular-expressions.info/powershell.html" target="_blank"&gt;Regular-Expressions.info&lt;/a&gt; website.)&lt;/p&gt;
&lt;p&gt;The result is a working script that adds two pieces of functionality. First, the script allows you to input a specific user to search for (or all users if no input is supplied). A technique called splatting is used to allow &amp;ldquo;@Params&amp;rdquo; to send additional optional parameters to the &lt;strong&gt;Get-Mailbox&lt;/strong&gt; cmdlet. Second, the script adds a new member to the mailbox statistics called &lt;strong&gt;TotalItemSizeInBytes&lt;/strong&gt;. With this member you can then convert to any byte level that suits your needs (for example, KB, MB, or GB).&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;You can download the full version of this script from the Script Center Repository (it includes commands to connect to Exchange Online session): &amp;nbsp;&lt;br /&gt; &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Get-Exchange-Online-a9dfbd44" target="_blank"&gt;Get Exchange Online Mailbox Size in GBs&lt;/a&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$userToFind = Read-Host -Prompt &amp;quot;Enter user to find (leave blank for all)&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$params = @{}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;if([string]::IsNullOrEmpty($userToFind) -eq $false)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{$params = @{Identity = $userToFind}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$UserMailboxStats = Get-Mailbox -RecipientTypeDetails UserMailbox `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; -ResultSize Unlimited @Params |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; Get-MailboxStatistics&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$UserMailboxStats |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; Add-Member -MemberType ScriptProperty -Name TotalItemSizeInBytes `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; -Value {$this.TotalItemSize -replace &amp;quot;(.*\()|,| [a-z]*\)&amp;quot;, &amp;quot;&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$UserMailboxStats |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; Select-Object DisplayName, TotalItemSizeInBytes,@{Name=&amp;quot;TotalItemSize (GB)&amp;quot;; `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; Expression={[math]::Round($_.TotalItemSizeInBytes/1GB,2)}}&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5008.hsg_2D00_2_2D00_27_2D00_13_2D00_3.jpg"&gt;&lt;img title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5008.hsg_2D00_2_2D00_27_2D00_13_2D00_3.jpg" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The regular expression&lt;strong&gt; &amp;lsquo;$this.TotalItemSize &amp;ndash;replace &amp;quot;(.*\()|,| [a-z]*\)&amp;quot;, &amp;quot;&amp;quot;&amp;rsquo;&lt;/strong&gt; is searching for the following three patterns and replacing them with empty strings. The result is the total item size in bytes with no other extra characters.&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;.*\( = Any number of characters followed by an opening parentheses&lt;/li&gt;
&lt;li&gt;, = Commas&lt;/li&gt;
&lt;li&gt;[a-z]*\) = Any number of alphabetic characters followed by a closing parentheses (i.e. &amp;ldquo;bytes)&amp;rdquo;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Moving from on-premises to the cloud with Windows PowerShell (and Windows PowerShell remoting in general) can sometimes present new challenges due to what you have access to. This means that you must always test your code and scripts.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3312.PHOTO.png"&gt;&lt;img title="Photo" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3312.PHOTO.png" alt="Photo" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I still believe that not having to physically RDP to a server is a huge gain over some of the small hurdles that you may encounter during the transition. Scripting is the future of administration, and it makes you more valuable. Hopefully this script and the concepts presented help you be a better admin and developer.&lt;/p&gt;
&lt;p&gt;For more information, watch my video series: &lt;a href="http://www.youtube.com/watch?v=Sg_h66HMP9o" target="_blank"&gt;The One Thing: Brian Jackett and SharePoint 2010&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;mdash;Frog Out&lt;/p&gt;
&lt;h3&gt;Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.technet.com/b/gary/archive/2010/02/20/the-get-mailboxstatistics-cmdlet-the-totalitemsize-property-and-that-pesky-little-b.aspx" target="_blank"&gt;The Get-MailboxStatistics cmdlet, the TotalItemSize property, and that pesky little &amp;ldquo;b&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://technet.microsoft.com/en-us/exchangelabshelp/gg576861#ViewAllMailboxes" target="_blank"&gt;View Mailbox Sizes and Mailbox Quotas Using Windows PowerShell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.regular-expressions.info/powershell.html" target="_blank"&gt;Regular Expressions with Windows PowerShell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Get-Exchange-Online-a9dfbd44" target="_blank"&gt;Get Exchange Online Mailboxes Size in GBs on TechNet Script Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.pinkelephant.com/images/uploads/conferences/I-dont-always-test-my-code-But-when-I-do-I-do-it-in-production.jpg" target="_blank"&gt;&amp;ldquo;I don&amp;rsquo;t always test my code&amp;hellip;&amp;rdquo; image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=Sg_h66HMP9o" target="_blank"&gt;The One Thing: Brian Jackett and SharePoint 2010&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Awesome job, Brian. Thanks for an informative and helpful guest blog post. Join me tomorrow when I will talk about using Windows PowerShell to explore process threads.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ed Wilson, Microsoft Scripting Guy&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3555059" width="1" height="1" alt="" /&gt;</description></item><item><title>Send Email from Exchange Online by Using PowerShell</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2011/09/24/send-email-from-exchange-online-by-using-powershell.aspx</link><pubDate>Sat, 24 Sep 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:12483</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;: Guest blogger Mike Pfeiffer shows how to send email messages using Windows PowerShell and Exchange online.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy Ed Wilson here. Guest Blogger Mike Pfeiffer recently published a book called &lt;a href="http://www.amazon.com/Microsoft-Exchange-2010-PowerShell-Cookbook/dp/1849682461/ref=sr_1_1?ie=UTF8&amp;amp;qid=1315850013&amp;amp;sr=8-1"&gt;Microsoft Exchange 2010 PowerShell Cookbook&lt;/a&gt;&lt;strong&gt;. &lt;/strong&gt;Mike has been in the IT field for over 13 years, spending most of his time as an enterprise consultant focused on Active Directory and Exchange implementation and migration projects. He is a Microsoft Certified Master on Exchange 2010, and a Microsoft Exchange MVP. You can find his writings online at &lt;a href="http://www.mikepfeiffer.net/"&gt;mikepfeiffer.net&lt;/a&gt;, where he blogs regularly about Exchange Server and Windows PowerShell-related topics.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Sending the output of a script in an email message is simple with Windows PowerShell 2.0, thanks to the &lt;b&gt;Send-MailMessage&lt;/b&gt; cmdlet. I have seen some great solutions people have created with this cmdlet to generate and deliver automated reports, notifications, and monitoring alerts. Even before Windows PowerShell 2.0, it was easy to use the classes in the &lt;b&gt;System.Net.Mail&lt;/b&gt; namespace to accomplish the same goal. In either case, as long as you have access to an SMTP server, you can easily automate the transmission of email messages with Windows PowerShell.&lt;/p&gt;
&lt;p&gt;Messaging is getting a little more complicated these days, though. Now we have hosted solutions such as Exchange Online offered through Office 365. Imagine that your organization has decided to go with a fully hosted deployment of Exchange Online, meaning that all of your organization&amp;rsquo;s mailboxes are hosted exclusively in the cloud. What do you do with your scripts that need to send email messages?&lt;/p&gt;
&lt;p&gt;Out of the box, SMTP Relay with Exchange Online requires a Transport Layer Security (TLS) connection, and you must connect on SMTP port 587. The good news is that there is an easier way to send email messages via Exchange Online using Windows PowerShell. The answer is the Exchange Web Services (EWS) Managed API, which is a fully object-oriented .NET Framework wrapper for the EWS XML protocol.&lt;/p&gt;
&lt;p&gt;Here are a few of the benefits to using EWS to send email messages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Messages are sent through the web services endpoint on port 443, which is firewall friendly.&lt;/li&gt;
&lt;li&gt;The API has a built-in autodiscover client that will determine the web service endpoint for you automatically. You don&amp;rsquo;t need to provide a server name.&lt;/li&gt;
&lt;li&gt;You don&amp;rsquo;t need to worry about connector settings, mail relay, and TLS.&lt;/li&gt;
&lt;li&gt;Messages sent through the API can be saved in the senders Sent Items folder, which can provide tracking and reporting information.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;In order to use the EWS Managed API and the code provided in this article, you&amp;rsquo;ll need a machine running Windows Server 2008 R2, Windows Server 2008, Windows 7, or Windows Vista. You&amp;rsquo;ll also need Windows PowerShell 2.0 with.NET Framework 3.5 installed. As long as these requirements are met, head over to the Microsoft Download Center and grab &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=13480"&gt;EWS Managed API 1.1&lt;/a&gt;. You will want to download the appropriate MSI package for your machine, either x86 or x64, and run through the installation. The installer simply extracts the EWS assembly to a folder on your hard drive, which by default will be under C:\Program Files\Microsoft\Exchange\Web Services\1.1&lt;/p&gt;
&lt;p&gt;After this is complete, we are ready to write some code. Before we can start working with the classes in the EWS Managed API, the assembly must be loaded so that the .NET Framework types are available:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Add-Type -Path &amp;#39;C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll&amp;#39;&lt;/p&gt;
&lt;p&gt;Next, we need to create an instance of the &lt;b&gt;ExchangeService&lt;/b&gt; class that can be used to send SOAP messages to an Exchange server using the API. This class basically defines the connection information for the web service. It provides several properties and methods, some of which can be used to specify our credentials and set the web services endpoint URL using the built-in autodiscover client:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2010_SP1&lt;/p&gt;
&lt;p&gt;Notice that we are passing the Exchange version to the &lt;b&gt;ExchangeService&lt;/b&gt; class constructor. This is actually optional in this case because the 1.1 version of the API will automatically set this to Exchange2010_SP1, which is the same version running in the cloud. However, it&amp;#39;s good to know if you ever want to write code that targets an Exchange server running on premise. The &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.exchangeversion%28v=exchg.80%29.aspx"&gt;ExchangeVersion Enumeration&lt;/a&gt; contains all of the supported versions that can be used.&lt;/p&gt;
&lt;p&gt;Since our goal is to send a message from Exchange Online, we will need to authenticate to the web service. This can be set on the existing &lt;b&gt;$service&lt;/b&gt; objects &lt;b&gt;Credentials&lt;/b&gt; property:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList&amp;nbsp; user@yourdomain.onmicrosoft.com, &amp;ldquo;P@ssw0rd&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The credentials used here should be the mailbox from which you want to send the email message. This will be a valid user name and password for an existing Exchange Online user account.&lt;/p&gt;
&lt;p&gt;At this point, we can use the &lt;b&gt;AutoDiscoverUrl&lt;/b&gt; method of the &lt;b&gt;$service&lt;/b&gt; object to automatically set the EWS end-point:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$service.AutodiscoverUrl(&amp;#39;user@yourdomain.onmicrosoft.com&amp;#39;, {$true})&lt;/p&gt;
&lt;p&gt;The first argument provided for the &lt;b&gt;AutoDiscoverUrl&lt;/b&gt; method is the e-mail address for your Exchange Online user account. The API will take the domain portion of the address and query DNS for an autodiscover record. Once it is resolved, the API will hit the autodiscover endpoint and determine the Exchange web services URL in the cloud. The second argument passed to the method is a scriptblock that returns &lt;b&gt;$true&lt;/b&gt;. This allows the server to redirect API to the appropriate Exchange Online server during the autodiscover process.&lt;/p&gt;
&lt;p&gt;If you take a look at the &lt;b&gt;$service&lt;/b&gt; object after invoking the &lt;b&gt;AutodiscoverUrl&lt;/b&gt; method, you&amp;rsquo;ll notice that the EWS URL is automatically set to an Exchange Online server running in the cloud.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5277.hsg_2D00_9_2D00_24_2D00_11_2D00_1.jpg"&gt;&lt;img style="border:0px;" title="Image of EWS URL automatically set to Exchange Online server running in cloud" alt="Image of EWS URL automatically set to Exchange Online server running in cloud" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5277.hsg_2D00_9_2D00_24_2D00_11_2D00_1.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now that we have an authenticated connection established to Exchange Online, we can create an instance of the &lt;b&gt;EmailMessage&lt;/b&gt; class and send a message:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service&lt;br /&gt;$message.Subject = &amp;#39;Test is a test&amp;#39;&lt;br /&gt;$message.Body = &amp;#39;This message is being sent through EWS with PowerShell&amp;#39;&lt;br /&gt;$message.ToRecipients.Add(&amp;lsquo;sysadmin@contoso.com&amp;rsquo;)&lt;br /&gt;$message.SendAndSaveCopy()&lt;/p&gt;
&lt;p&gt;Setting the &lt;b&gt;Subject&lt;/b&gt;, &lt;b&gt;Body&lt;/b&gt;, and &lt;b&gt;From&lt;/b&gt; properties of an &lt;b&gt;EmailMessage&lt;/b&gt; object is pretty straightforward.&amp;nbsp; Adding recipients requires that we use the &lt;b&gt;Add&lt;/b&gt; method of the &lt;b&gt;ToRecipients&lt;/b&gt; property. When adding multiple recipients, you can call this method for each one. There are also properties for &lt;b&gt;CcRecipients&lt;/b&gt; and &lt;b&gt;BccRecipients&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;When it comes to actually sending the message, there are two methods that can be used. The &lt;b&gt;SendAndSaveCopy&lt;/b&gt; method sends the message and retains a copy in the senders Sent Items folder. Alternatively, the &lt;b&gt;Send&lt;/b&gt; method will send the message without saving a copy. Because we passed the &lt;b&gt;$service&lt;/b&gt; object to the &lt;b&gt;EmailMessage&lt;/b&gt; class constructor when creating the message, our Exchange Online credentials and web services endpoint located through autodiscover will be used to transmit the message.&lt;/p&gt;
&lt;p&gt;While the code we have looked at so far is useful, we can automate things even further. Let us wrap the code up into a reusable function to make this a little easier.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;function Send-O365MailMessage {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [CmdletBinding()]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; param(&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position=1, Mandatory=$true)]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [String[]]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $To,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position=2, Mandatory=$false)]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [String[]]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $CcRecipients,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position=3, Mandatory=$false)]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [String[]]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $BccRecipients,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position=4, Mandatory=$true)]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [String]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $Subject,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position=5, Mandatory=$true)]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [String]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $Body,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position=6, Mandatory=$false)]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Switch]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $BodyAsHtml,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position=7, Mandatory=$true)]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [System.Management.Automation.PSCredential]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $Credential&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Load the EWS Managed API Assembly&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Add-Type -Path &amp;#39;C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll&amp;#39;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; process {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Insatiate the EWS service object&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2010_SP1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Set the credentials for Exchange Online&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList `&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $Credential.UserName, $Credential.GetNetworkCredential().Password&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Determine the EWS endpoint using autodiscover&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $service.AutodiscoverUrl($Credential.UserName, {$true})&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Create the email message and set the Subject and Body&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $message.Subject = $Subject&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $message.Body = $Body&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #If the -BodyAsHtml parameter is not used, send the message as plain text&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(!$BodyAsHtml) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $message.Body.BodyType = &amp;#39;Text&amp;#39;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Add each specified recipient&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $To | ForEach-Object{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $null = $message.ToRecipients.Add($_)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Add each specified carbon copy recipient&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if($CcRecipients) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $CcRecipients | ForEach-Object{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $null = $message.CcRecipients.Add($_)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Add each specified blind copy recipient&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if($BccRecipients) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $BccRecipients | ForEach-Object{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $null = $message.BccRecipients.Add($_)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Send the message and save a copy in the Sent Items folder&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $message.SendAndSaveCopy()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This function provides several parameters used to set the subject, body, and recipients for the message. The &lt;i&gt;To&lt;/i&gt;, &lt;i&gt;CcRecipients&lt;/i&gt;, and &lt;i&gt;BccRecipients&lt;/i&gt; parameters accept multiple addresses and you can specify one or more addresses for each recipient type when sending a message. I&amp;rsquo;ve also included a &lt;i&gt;BodyAsHtml&lt;/i&gt; switch parameter, which can be used to send the message in HTML format&amp;mdash;or in plain text, when the parameter is not used.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After you have added this function to your shell session, you can call it just like a cmdlet and send a message through the web service:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$creds = Get-Credential&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Send-O365MailMessage -To user@domain.com -Subject &amp;#39;test&amp;#39; -Body &amp;#39;this is a test&amp;#39; -BodyAsHtml -Credential $creds&lt;/p&gt;
&lt;p&gt;This code first uses the &lt;b&gt;Get-Credential cmdlet&lt;/b&gt; to store your Exchange Online credentials. We then call the &lt;b&gt;Send-O365MailMessage&lt;/b&gt; cmdlet to send an email message through Exchange Online.&lt;/p&gt;
&lt;p&gt;As a side note, EWS works the same on premise as it does in the cloud. If you have an existing Exchange 2010 SP1 deployment onsite, you can use the code samples in this article to send messages through the web service on your on-premise servers.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thank you, Mike, for sharing your knowledge and experience with us today.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3454496" width="1" height="1" alt="" /&gt;</description></item><item><title>A PowerShell Exchange Best Practices Analyzer XML Parser</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2011/09/05/a-powershell-exchange-best-practices-analyzer-xml-parser.aspx</link><pubDate>Mon, 05 Sep 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:12123</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: In this guest blog post, you will learn how to create a Windows PowerShell parser to parse the XML file generated using ExBPAcmd.exe.&lt;/p&gt;
&lt;p class="CodeBlock"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy Ed Wilson here. I want to welcome our Guest Blogger Thiyagu again today. Here is a little about Thiyagu:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;I am the founder of the &lt;a href="http://www.powershellgroup.org/Singapore"&gt;&lt;b&gt;Singapore PowerShell User Group&lt;/b&gt;&lt;/a&gt;. I am an Exchange administrator, and I have been scripting for more than seven years now. Before Windows PowerShell, I did most of my scripting in VBScript. With Windows PowerShell, I automate Exchange/Active Directory tasks, and I am also good at WMI, ADSI, and generating custom reports. I have developed custom applications in C# for automation. I love to automate things! You will find me on &lt;a href="http://www.myexchangeworld.com/"&gt;&lt;b&gt;my blog&lt;/b&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3426.HSG_2D00_9_2D00_5_2D00_11_2D00_1.jpg"&gt;&lt;img style="border:0px;" title="Photo of Thiyagu" alt="Photo of Thiyagu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3426.HSG_2D00_9_2D00_5_2D00_11_2D00_1.jpg" width="300" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;What Is the Best Practices Analyzer?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The Best Practices Analyzer (BPA) is a server management tool that is available in Windows Server 2008 R2. BPA can help administrators reduce best practices violations by scanning one or more roles that are installed on Windows Server 2008 R2, and reporting best practices violations to the administrator. Administrators can filter or exclude results from BPA reports that they don&amp;rsquo;t need to see. Administrators can also perform BPA tasks by using either the Server Manager GUI, or Windows PowerShell cmdlets.&lt;/p&gt;
&lt;p&gt;BPA is part of the Windows Server 2008 R2, and you can run it on most of the roles installed on the server.&lt;/p&gt;
&lt;p&gt;The following list includes some of the roles against which you can run BPA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Active Directory Domain Services&lt;/li&gt;
&lt;li&gt;Active Directory Certificate Services&lt;/li&gt;
&lt;li&gt;Domain Name System (DNS) Server&lt;/li&gt;
&lt;li&gt;Remote Desktop Services&lt;/li&gt;
&lt;li&gt;Web Server (IIS)&lt;/li&gt;
&lt;li&gt;Active Directory Rights Management Services (AD RMS)&lt;/li&gt;
&lt;li&gt;Application Server&lt;/li&gt;
&lt;li&gt;DHCP&lt;/li&gt;
&lt;li&gt;File Services&lt;/li&gt;
&lt;li&gt;Hyper-V&lt;/li&gt;
&lt;li&gt;Network Policy Server (NPS)&lt;/li&gt;
&lt;li&gt;Windows Server Update Services (WSUS)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can use the following Windows PowerShell cmdlets to work with the various Best Practices Analyzers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get-BPAModel&lt;/li&gt;
&lt;li&gt;Get-BPAResult&lt;/li&gt;
&lt;li&gt;Invoke-BPAModel&lt;/li&gt;
&lt;li&gt;Set-BPAResult&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read more about &lt;a href="http://technet.microsoft.com/en-us/library/dd759206.aspx#BKMK_PSscan"&gt;BPA cmdlets&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But today&amp;rsquo;s topic is about the Exchange BPA, and we cannot run those cmdlets against Exchange. Instead, Exchange 2010 has its own ExBPA installed with it. I will explain how you can use Windows PowerShell to automate this. Here is how the GUI looks.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3644.HSG_2D00_9_2D00_5_2D00_11_2D00_2.jpg"&gt;&lt;img style="border:0px;" title="Image of ExBPA interface" alt="Image of ExBPA interface" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3644.HSG_2D00_9_2D00_5_2D00_11_2D00_2.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can use the GUI to scan a given set of servers and specify the type of scan, and this will do all the work for you. But as an Exchange Administrator, you should be doing this on a weekly or monthly basis. So here is how you can do this in an automated way.&lt;/p&gt;
&lt;p&gt;In the build, there is an executable that comes with ExBPA called ExBPACmd.exe, which is kind of the command line version of the GUI. Here are some of the important parameters for the ExBPACmd.exe:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-dat &amp;lt;file&amp;gt;&amp;nbsp; Write the output data to &amp;lt;file&amp;gt;.&amp;nbsp; The default is&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output.&amp;lt;label&amp;gt;.&amp;lt;timestamp&amp;gt;.xml in the exbpa output directory.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; -d &amp;lt;server&amp;gt;&amp;nbsp; Access the directory using the global catalog server &amp;lt;server&amp;gt;.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If not given, it will bind to the nearest one.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; -r &amp;lt;option&amp;gt;[=&amp;lt;value&amp;gt;][,...]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Restrict the collection/analysis to include the specified&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; restriction.&amp;nbsp; The default is &amp;quot;Health Check&amp;quot;.&lt;/p&gt;
&lt;p&gt;Here are the valid restriction options:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Scope: Server,AdminGroup,Organization,Domain,ADC Server,_&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Role:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Mailbox,Gateway,Bridgehead,ClientAccess,UnifiedMessaging,Global,AdminTools,LanguagePacks,UmLanguagePack&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Task: Health,Perf,Permissions,UserPermissions,ConnectivityTask,BaselineTask,PrecheckInstall,PrecheckUninstall,PrecheckUpgrade,PrecheckDR,Postcheck&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Level: 1,2,3,4,5&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Category:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;General,Performance,Security,EndUserPermissions,Connectivity,Baseline,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;CustomBaseline,Prereqs&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here is a sample command:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;ExBPACmd.exe -dat test.xml -r &amp;quot;Health,5,Server=Van-EX1&amp;quot;&lt;/p&gt;
&lt;p&gt;The preceding command will start an ExBPA scan type of health and level 5 and on server &amp;ldquo;Van-Ex1&amp;rdquo;; it will output the data to test.xml. You can put this command in your little script and call the program from within Windows PowerShell. You should then finally end up having the XML file. Now the fun stuff starts.&lt;/p&gt;
&lt;p&gt;Here is what the XML looks like when you view it using ExBPA.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0172.HSG_2D00_9_2D00_5_2D00_11_2D00_3.jpg"&gt;&lt;img style="border:0px;" title="Image of how the XML looks when viewed in ExBPA" alt="Image of how the XML looks when viewed in ExBPA" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0172.HSG_2D00_9_2D00_5_2D00_11_2D00_3.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each of these entries is present in the XML file and we have to get them out. Here is a sample of one of those items from the XML piece:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;Message Name=&amp;quot;fDiskDriverAgeWarning&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Query=&amp;quot;get-days(date-difference($dCurrentDateTime/Result, (date-parse(substring(($_/../Value | $_/../Instance),1,8), &amp;#39;yyyyMMdd&amp;#39;)))) &amp;amp;gt;730&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Error=&amp;quot;Warning&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Title=&amp;quot;Storage driver is more than two years old&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Text=&amp;quot;Storage driver file &amp;#39;{5}&amp;#39; for &amp;#39;{1}&amp;#39; on server {2} is more than two years old. Check with your vendor to find out if a newer version is available. Installed driver details: {6} - {8}&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;P1=&amp;quot;LSI Adapter, SAS 3000 series, 8-port with 1068&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;P2=&amp;quot;VAN-EX1.Adatum.com&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;P5=&amp;quot;c:\windows\system32\drivers\lsi_sas.sys&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;P6=&amp;quot;1.28.3.52&amp;quot; P8=&amp;quot;20090714094804.350065+480&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;EventID=&amp;quot;2408&amp;quot; Pass=&amp;quot;True&amp;quot;&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Storage driver file &amp;#39;c:\windows\system32\drivers\lsi_sas.sys&amp;#39; for &amp;#39;LSI Adapter, SAS 3000 series, 8-port with 1068&amp;#39; on server VAN-EX1.Adatum.com is more than two years old. Check with your vendor to find out if a newer version is available. Installed driver details: 1.28.3.52 - 20090714094804.350065+480&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;/Message&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I just formatted the XML code so that it is more readable. Notice that there are different attributes for the &lt;b&gt;Message&lt;/b&gt; node. Here are the ones on which we will focus:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Error&lt;/li&gt;
&lt;li&gt;Title&lt;/li&gt;
&lt;li&gt;Text&lt;/li&gt;
&lt;li&gt;P2&lt;/li&gt;
&lt;li&gt;P3&lt;/li&gt;
&lt;li&gt;InnerText&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It is so easy to parse XML with Windows PowerShell, and within two lines, you can get what you need:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$xmlFile = [xml](Get-Content test.xml)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$parseddata = $xmlFile.SelectNodes(&amp;quot;ObjectCollector//Message&amp;quot;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The first line gets the content of the test.xml file and turns it into XML. You can see this with &lt;b&gt;Get-Member&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4251.HSG_2D00_9_2D00_5_2D00_11_2D00_4.jpg"&gt;&lt;img style="border:0px;" title="Image of first line of text.xml being turned into XML" alt="Image of first line of text.xml being turned into XML" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4251.HSG_2D00_9_2D00_5_2D00_11_2D00_4.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;On the next line, I use a method of the &lt;b&gt;System.Xml.XmlDocument&lt;/b&gt; called &lt;b&gt;SelectNodes&lt;/b&gt;. You can read more about &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.selectnodes.aspx"&gt;this method&lt;/a&gt;. The idea is that you can pass an &lt;a href="http://msdn.microsoft.com/en-us/library/ms256471.aspx"&gt;XPath&lt;/a&gt; Expression, which is a way of narrowing down what you want out of the XML file. In this case, I am passing the string, &lt;b&gt;ObjectCollector//Message&lt;/b&gt;. The first two lines of the XML are shown in the following figure.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2043.HSG_2D00_9_2D00_5_2D00_11_2D00_5.jpg"&gt;&lt;img style="border:0px;" title="Image of first two lines of the XML" alt="Image of first two lines of the XML" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2043.HSG_2D00_9_2D00_5_2D00_11_2D00_5.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The root node is called &lt;b&gt;ObjectCollector&lt;/b&gt;, so the first of the string is saying start the search from the root. The&lt;strong&gt; //&lt;/strong&gt; means give me all the nodes from &lt;b&gt;ObjectCollector&lt;/b&gt; onward, which are called &lt;b&gt;Message&lt;/b&gt;. What we get out of the next line of code is a collection of XML elements. See the image below for details of the &lt;b&gt;XMLElement&lt;/b&gt; object.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5417.HSG_2D00_9_2D00_5_2D00_11_2D00_6.jpg"&gt;&lt;img style="border:0px;" title="Image of details of XMLElement object" alt="Image of details of XMLElement object" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5417.HSG_2D00_9_2D00_5_2D00_11_2D00_6.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each of the elements has an attribute called &lt;b&gt;Error&lt;/b&gt;, and they have six possible options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Error&lt;/li&gt;
&lt;li&gt;Warning&lt;/li&gt;
&lt;li&gt;None (which means Information)&lt;/li&gt;
&lt;li&gt;NonDefault&lt;/li&gt;
&lt;li&gt;Baseline&lt;/li&gt;
&lt;li&gt;BestPractice&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can pipe the data to &lt;b&gt;Where-Object&lt;/b&gt; and filter on the desired output. The following command returns only warning messages:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$parseddata | Where-Object {$_.Error -eq &amp;quot;Warning&amp;quot;}&lt;/p&gt;
&lt;p&gt;With this in mind, I created an advanced function that accepts two input parameters: &lt;b&gt;InputFileName&lt;/b&gt; and &lt;b&gt;InformationType&lt;/b&gt;. The function returns the matching XML element objects out to the pipeline. You pipe the output from the advanced function to the &lt;b&gt;ConvertTo-HTML&lt;/b&gt; cmdlet and then use the &lt;b&gt;Send-Mailmessage&lt;/b&gt; cmdlet has a report sent to your mailbox.&lt;/p&gt;
&lt;p&gt;Add a scheduled task to do this periodically and you are good to go. No need to manually run the GUI again for this:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;.\Parse-XML.ps1 -InputFileName .\ExBPA.xml | ConvertTo-Html | Out-File &amp;ldquo;ExBPAReport.HTML&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Download the &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/680b3a66-2b7b-4baa-b178-0c1c1323be8d"&gt;complete script&lt;/a&gt; from the Script Center Script Repository.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thank you, Thiyagu, for once again sharing your knowledge. I love the way that you wrap up with your function and suggestion for creating a scheduled task to generate a report. Cool.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3449498" width="1" height="1" alt="" /&gt;</description></item><item><title>Analyze Email Message Headers with PowerShell—Part 2</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2011/08/19/analyze-email-message-headers-with-powershell-part-2.aspx</link><pubDate>Fri, 19 Aug 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:11890</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: Learn how to use Windows PowerShell to analyze email headers and obtain detailed origination information.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="CodeBlock"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy Ed Wilson here. Guest Blogger Thiyagu continues with part 2 of his post about analyzing email headers with Windows PowerShell. See yesterdays&amp;rsquo; post for information about Thiyagu and for the first part of the article.&lt;/p&gt;
&lt;p&gt;In part 1, we saw how to use &lt;b&gt;Regex&lt;/b&gt; and parse the email message header. So far, we have a &lt;b&gt;PSObject&lt;/b&gt; with all the required properties parsed from the email message header. Sometimes with certain types of headers, you will have another set of headers. Instead of having just the &amp;ldquo;Received: from,&amp;rdquo; there will also be one named &amp;ldquo;Received: by.&amp;rdquo; I also wrote another function, just like this one to process that information as well as to build a custom &lt;b&gt;PSObject&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;Both of these functions will return a collection of &lt;b&gt;PSObjects&lt;/b&gt;. Remember in part 1, I mentioned that we should be reading the email message header from bottom up, but we did not do that. We were doing this from top down. You can use this approach to reverse an array of objects:&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$byObjects = $byObjects[($byObjects.Length-1)..0] # Reversing the Array&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Alternatively, for large arrays, using the static &lt;b&gt;Reverse&lt;/b&gt; method from the &lt;b&gt;Array&lt;/b&gt; class will have much better performance. This technique is shown here:&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;[Array]::Reverse($byObjects)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now we have two objects: one from &amp;ldquo;Received: from&amp;rdquo; and another from &amp;ldquo;Received: by.&amp;rdquo; &amp;ldquo;Received:&amp;nbsp; by&amp;rdquo; sections come first and then &amp;ldquo;Received:&amp;nbsp; from.&amp;rdquo; Now, enter the main function, which is going to do all the work.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The main function takes both the &lt;b&gt;receivedby&lt;/b&gt;&lt;i&gt; &lt;/i&gt;and the &lt;b&gt;receivedfrom&lt;/b&gt; objects. The function starts with the &lt;b&gt;receivedby&lt;/b&gt; object first, because it is the first part that starts. It then takes the server name and the protocol (if available) and continues on to the next object in the array of objects that is passed. The function now starts its calculation, and compares the time of the previous entry with the time of the current entry. The function obtains the difference between the two time stamps and calculates the number of seconds.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After it has this information, it is stored in a variable called &lt;b&gt;$delay&lt;/b&gt;. This delay value is later added to the final &lt;b&gt;PSObject&lt;/b&gt;, which will have all the info gathered from the headers. Here is what the function looks like; I am posting only the partial function here to show you the portion that matters:&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;if($fromObjects)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;$fromObjects = $fromObjects[($fromObjects.Length-1)..0] #Reversing the Array&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;for($index = 0;$index -lt $fromobjects.Count;$index++)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $hop = $hop + 1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $receivedfrom = $fromobjects[$index].ReceivedFromFrom&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $receivedby = $fromobjects[$index].ReceivedFromBy&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $with = $fromobjects[$index].ReceivedFromWith&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $time = $fromobjects[$index].ReceivedFromTime&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $time = $time.touniversaltime()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if($prevTime)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $delay = $time - $prevTime&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $delay = $delay | Select-Object -ExpandProperty totalseconds&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $delay = &amp;quot;*&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $prevTime = $time&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $finalHash = @{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Hop&amp;nbsp;&amp;nbsp; = $hop&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Delay = $delay&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; From&amp;nbsp; = $receivedfrom&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; By &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;= $receivedby&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; With&amp;nbsp; = $with&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Time&amp;nbsp; = $time&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $obj = New-Object -TypeName PSObject -Property $finalHash&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $finalArray += $obj&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;These are all the fields we need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hop&lt;/li&gt;
&lt;li&gt;Delay&lt;/li&gt;
&lt;li&gt;From&lt;/li&gt;
&lt;li&gt;By&lt;/li&gt;
&lt;li&gt;With&lt;/li&gt;
&lt;li&gt;Time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also notice that I am converting all the times to universal time (UTC), so this way we have one set of times instead of all different time zones such IST, PDT, and EST.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Delay is calculated by subtracting the time of the previous hop from the current time value:&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$delay = $time - $prevTime&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$delay = $delay.totalseconds&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Then I just get the &lt;b&gt;totalseconds&lt;/b&gt; property. Now let us just build a &lt;b&gt;PSObject&lt;/b&gt; with all these parameters and then we are good to go. Finally it out that &lt;b&gt;PSObject&lt;/b&gt; onto a gridview and here is what I get:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7624.hsg_2D00_8_2D00_19_2D00_11_2D00_1.png"&gt;&lt;img style="border:0px;" alt="Image of gridview" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7624.hsg_2D00_8_2D00_19_2D00_11_2D00_1.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can see now easily that on hop two, it took eight seconds, and in the next hop, it took around five seconds. Finally, there was delay of six seconds to submit to the server &amp;ldquo;incoming.green.com&amp;rdquo;. I converted the script to an advanced function, which takes in &lt;b&gt;Filename&lt;/b&gt; as an input to parse the information. You can use it like a cmdlet and I have included some examples as well. The complete script containing the advanced function can be downloaded from the &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/8c15881d-c10f-4309-9900-4ff0653987a5"&gt;Scripting Guys Script Repository&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Usually Level 1 teams do this type of job of checking these headers. I think we should give them a tool to do this work, instead of giving them this big Windows PowerShell script. Therefore, here is how I put together the GUI piece for this tool. I used &lt;a href="http://showui.codeplex.com/"&gt;ShowUI&lt;/a&gt; to build this tool in 15 lines. Here is the code:&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;[System.Reflection.Assembly]::LoadWithPartialName(&amp;quot;System.windows.forms&amp;quot;) | Out-Null&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$OpenFileDialog.ShowDialog() | Out-Null&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$filename = $openfiledialog.FileName&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$data = c:\Scripts\MSGHeaderProcessor\Parse-EmailHeader.ps1 -InputFileName $filename&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-Window -Title &amp;quot;Email Header Parser&amp;quot; -SizeToContent WidthAndHeight -Show {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-DataGrid -Name MessageHeader -Columns {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-DataGridTextColumn -Header &amp;quot;Hop&amp;quot; -Binding {Binding -Path &amp;quot;Hop&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-DataGridTextColumn -Header &amp;quot;Delay(Seconds)&amp;quot; -Binding {Binding -Path &amp;quot;Delay&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-DataGridTextColumn -Header &amp;quot;From&amp;quot; -Binding {Binding -Path &amp;quot;From&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-DataGridTextColumn -Header &amp;quot;By&amp;quot; -Binding {Binding -Path &amp;quot;By&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-DataGridTextColumn -Header &amp;quot;With&amp;quot; -Binding {Binding -Path &amp;quot;With&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-DataGridTextColumn -Header &amp;quot;Time(UTC)&amp;quot; -Binding {Binding -Path &amp;quot;Time&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } -ItemsSource $data&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The first four lines are about showing the Windows Open Dialog box and getting the file name that the user wants to parse. I then call the script with that file name as the input and store the value in the &lt;b&gt;$data&lt;/b&gt; variable, which now is the &lt;b&gt;PSObjects&lt;/b&gt; collection.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next comes the ShowUI code. I create a new window and inside that I create a &lt;b&gt;datagrid&lt;/b&gt;. Inside the &lt;b&gt;datagrid&lt;/b&gt;, I add one datagridcolumn for each of the properties of the &lt;b&gt;PSObject&lt;/b&gt;. The interesting thing here is the &lt;i&gt;&amp;ndash;Binding&lt;/i&gt; parameter:&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-Binding {Binding &amp;ndash;Path &amp;ldquo;Hop&amp;rdquo;}&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The parameter checks the &lt;b&gt;itemsource&lt;/b&gt; property of the &lt;b&gt;datagrid&lt;/b&gt;, it uses the &lt;b&gt;Hop&lt;/b&gt; property of the object there, and then it populates that information in the grid.&amp;nbsp;The output from the ShowUI code is shown in the following figure.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4375.hsg_2D00_8_2D00_19_2D00_11_2D00_2.png"&gt;&lt;img style="border:0px;" title="Image of output from ShowUI code" alt="Image of output from ShowUI code" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4375.hsg_2D00_8_2D00_19_2D00_11_2D00_2.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Therefore, in 15 lines we could make a reusable tool and distribute it to the teams. The complete code can be downloaded from the &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/8c15881d-c10f-4309-9900-4ff0653987a5"&gt;Scripting Guys Script Repository&lt;/a&gt;. I have only uploaded the Advanced function there; you can use the ShowUI code in the article to get the GUI part of it.&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;b&gt;Note&lt;/b&gt;&amp;nbsp; &amp;nbsp;I have tested this with many headers, and it works well with Microsoft Header Version 2.0 headers, but I have not done testing on any old or different types of headers. If you guys notice any parsing issue on any header, please let me know.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I want to thank Thiyag for an awesome two-part series of articles about parsing email headers. Well done!&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3447472" width="1" height="1" alt="" /&gt;</description></item><item><title>Use PowerShell to Parse Email Message Headers—Part 1</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2011/08/18/use-powershell-to-parse-email-message-headers-part-1.aspx</link><pubDate>Thu, 18 Aug 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:11881</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: Guest Blogger Thiyagu teaches how to use Windows PowerShell to parse and analyze email message headers.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy Ed Wilson here. Thiyagarajan Parthiban is our guest blogger today with an interesting article about using Windows PowerShell to analyze Exchange email. First, though, let&amp;rsquo;s learn something about Thiyagu.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;I am the founder of the &lt;a href="http://www.powershellgroup.org/Singapore"&gt;Singapore PowerShell User Group&lt;/a&gt;. I am an Exchange administrator, and I have been scripting for more than seven years now. Before Windows PowerShell, I did most of my scripting in VBScript. With Windows PowerShell, I automate Exchange/Active Directory tasks, and I am also good at WMI, ADSI, and generating custom reports. I have developed custom applications in C# for automation. I love to automate things!&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;You will find me on &lt;a href="http://www.myexchangeworld.com/"&gt;my blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Take it away, Thiyagu!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Last year, a survey was conducted to figure out the number of email messages sent every day across the globe. It was estimated that approximately 294 billion messages per day are sent, which is 2.8 million messages per second. By the way, 90 percent of all email is either spam or viruses.&lt;/p&gt;
&lt;p&gt;Each and every email message you send or receive has a piece of information in it called a &lt;i&gt;message header&lt;/i&gt;. Every email message you receive in your inbox has this information. There are different ways to view this message header, depending on which email client you are using. For example, here are &lt;a href="http://blogs.msexchange.org/walther/2009/09/07/problems-finding-the-message-header-in-outlook-2010/"&gt;instructions for getting the message header&lt;/a&gt; of an email address if you are using Outlook 2010. The following figure shows how a message header looks.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3782.HSG_2D00_8_2D00_18_2D00_11_2D00_1.jpg"&gt;&lt;img style="border:0px;" title="Image of a message header" alt="Image of a message header" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3782.HSG_2D00_8_2D00_18_2D00_11_2D00_1.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;This text information contains a lot of details about the message you have received. &lt;a href="http://www.ietf.org/rfc/rfc2822.txt"&gt;RFC 822&lt;/a&gt; tells how to place information about an email message into this header.&lt;/p&gt;
&lt;p&gt;For now, focus on the green box in the preceding figure. This section has information about how this message got to your inbox. For an email to come to your inbox, it takes so many routes. That is our main focus in today&amp;rsquo;s post: we want to get this data parsed out of this messy text and present it in a nice little table so that you can understand what really happened with that email message.&lt;/p&gt;
&lt;p&gt;Whenever you try to make sense of an email message header, read it from the bottom up. The above piece of code has only four lines and is cut into different lines. Here is how it looks after removing the unwanted lines:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8623.HSG_2D00_8_2D00_18_2D00_11_2D00_2.jpg"&gt;&lt;img style="border:0px;" title="Image of message header with unwanted lines" alt="Image of message header with unwanted lines" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8623.HSG_2D00_8_2D00_18_2D00_11_2D00_2.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You see, it looks already a lot cleaner, after you remove those extra lines. Take a look at the boxes and circles in the image above, and read it like this:&lt;/p&gt;
&lt;p&gt;Received the email from Server &amp;ldquo;Corp.red.com ([16.25.5.17])&amp;rdquo; by Server &amp;ldquo;Singapore.red.com ([15.60.22.16])&amp;rdquo; with protocol &amp;ldquo;mapi id 14.01.0323.002&amp;rdquo; and at time &amp;ldquo;Wed, 13 Jul 2011 18:50:16 +0800&amp;rdquo; , which is UTC +8 (which is Singapore), you can tell from the server which received the message it says &amp;ldquo;Singapore.red.com&amp;rdquo;&lt;/p&gt;
&lt;p&gt;If that did not make much sense, it might help to visualize it like in the following figure.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7382.HSG_2D00_8_2D00_18_2D00_11_2D00_3.jpg"&gt;&lt;img style="border:0px;" title="Image of a hop from one server to another" alt="Image of a hop from one server to another" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7382.HSG_2D00_8_2D00_18_2D00_11_2D00_3.jpg" width="411" height="196" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, this server will send the message again to another server and so on. Each trip from server to server is called a &lt;i&gt;hop&lt;/i&gt;. The hop chain continues until it finally reaches your inbox. At times, there might be a delay when going through one of these chains. Maybe a server was busy or there was too much load, which could cause delays to email being delivered to your inbox. In this example, we have four lines, so we have four hops for the email to reach your mailbox.&lt;/p&gt;
&lt;p&gt;Enough of theory. Let&amp;rsquo;s talk about Windows PowerShell, starting with another figure.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8741.HSG_2D00_8_2D00_18_2D00_11_2D00_4.jpg"&gt;&lt;img style="border:0px;" title="Image of patterns in message header" alt="Image of patterns in message header" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8741.HSG_2D00_8_2D00_18_2D00_11_2D00_4.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We have to extract the piece of information between the above-mentioned sections to form our objects. You can see from the preceding screenshot that it has a pattern. Luckily, this is where regular expressions come to the rescue. Read this great article by PowerShell MVP Tome about &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2011/03/04/use-powershell-regular-expressions-to-parse-an-rss-feed.aspx"&gt;regular expressions and Windows PowerShell&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We need to get four pieces of information from each line:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;All text after &lt;i&gt;Received: from&lt;/i&gt; until there is a word called &lt;i&gt;by&lt;/i&gt;. This will be our Received From Server information.&lt;/li&gt;
&lt;li&gt;All text after &lt;i&gt;by&lt;/i&gt; until there is a word called &lt;i&gt;with.&lt;/i&gt; This info will be the server who receives the email from the server above.&lt;/li&gt;
&lt;li&gt;All text after &lt;i&gt;with&lt;/i&gt;, until there is a character &lt;i&gt;;&lt;/i&gt; (a semicolon) and this is the protocol.&lt;/li&gt;
&lt;li&gt;All text after &lt;i&gt;;&lt;/i&gt; (a semicolon) and get the next minimum 32 to 36 space/nonspace data.&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;This data is the date. Here is a sample date:&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&amp;nbsp;Wed, 20 Jul 2011 22:28:16 -0700. This is the maximum possible for standard time, so we can get other data as well. Sometimes, there might be space or there is new line, so I am giving myself a buffer, so later we can remove unwanted data from this string.&lt;/li&gt;
&lt;/ol&gt;&lt;/ol&gt;&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;Here is the regular expression pattern I came up with:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$regexFrom1 = &amp;#39;Received: from([\s\S]*?)by([\s\S]*?)with([\s\S]*?);([(\s\S)*]{32,36})(?:\s\S*?)&amp;#39;&lt;/p&gt;
&lt;p&gt;Can you believe, that the above regular expression pattern can do all four of the things I said above? If you are good at Windows PowerShell and still haven&amp;rsquo;t used regular expressions, you are missing an important weapon in your Windows PowerShell arsenal.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;b&gt;Note&amp;nbsp; &lt;/b&gt;&amp;nbsp;Check out this &lt;a href="http://richardspowershellblog.wordpress.com/2011/03/23/regular-expression-recording/"&gt;webcast&lt;/a&gt; by Tome. It is a great introduction to regular expressions.&lt;/p&gt;
&lt;p&gt;Because we do not know how the text is going to be in the message header, it is good to read the whole data as one long string and work with it. Here is the technique to do read a file into one big string.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$text = [System.IO.File]::OpenText(&amp;quot;C:\Scripts\msg6.txt&amp;quot;).ReadToEnd()&lt;/p&gt;
&lt;p&gt;His file now has the same information as the first screenshot in this post. I wanted to write a function that would take this &lt;b&gt;$text&lt;/b&gt; as input, process the string, give out all the parsed data, package it in an array of &lt;b&gt;PSObjects&lt;/b&gt;, and return them. I used &lt;b&gt;Select-String&lt;/b&gt; along with the regular expression pattern and iterated through all the matches I got.&lt;/p&gt;
&lt;p&gt;Here is how I did that:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function Process-ReceivedFrom&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Param($text)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$regexFrom1 = &amp;#39;Received: from([\s\S]*?)by([\s\S]*?)with([\s\S]*?);([(\s\S)*]{32,36})(?:\s\S*?)&amp;#39;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$fromMatches = $text | Select-String -Pattern $regexFrom1 -AllMatches&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;if ($fromMatches)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $rfArray = @()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $fromMatches.Matches | foreach{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $from = Clean-string $_.groups[1].value&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $by = Clean-string $_.groups[2].value&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $with = Clean-string $_.groups[3].value&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Switch -wildcard ($with)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;quot;SMTP*&amp;quot; {$with = &amp;quot;SMTP&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;quot;ESMTP*&amp;quot; {$with = &amp;quot;ESMTP&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;default{}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $time = Clean-string $_.groups[4].value&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $fromhash = @{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ReceivedFromFrom = $from&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ReceivedFromBy = $by&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ReceivedFromWith = $with&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ReceivedFromTime = [Datetime]$time&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $fromArray = New-Object -TypeName PSObject -Property $fromhash&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $rfArray += $fromArray&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $rfArray&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;else&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $null&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;To explain the regular expression a little bit:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;#39;Received: from([\s\S]*?)by([\s\S]*?)with([\s\S]*?);([(\s\S)*]{32,36})(?:\s\S*?)&amp;#39;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Each of those is matched into groups and then you can access them using the &lt;b&gt;matches&lt;/b&gt; property. This is true except for the last one (in the world of regular expressions, &amp;ldquo;?:&amp;rdquo; means don&amp;rsquo;t group them). This is the class it will get stored in: &lt;b&gt;Microsoft.PowerShell.Commands.MatchInfo&lt;/b&gt;.&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;I just loop through the matches and then build a &lt;b&gt;PSObject&lt;/b&gt; for each of the matches. Now, if I output the results of the function to a gridview, I see what is shown in the following figure:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1586.HSG_2D00_8_2D00_18_2D00_11_2D00_5.jpg"&gt;&lt;img style="border:0px;" title="Image of results of function in gridview" alt="Image of results of function in gridview" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1586.HSG_2D00_8_2D00_18_2D00_11_2D00_5.jpg" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Read the next part tomorrow, where I show how I put the pieces together to get delay information from different hops and then finally to build a GUI tool for this functionality.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thiyagu, this is an excellent article. Thank you for sharing your time with us and for sharing your expertise with the Windows PowerShell community. I am really looking forward to part 2 tomorrow!&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3447690" width="1" height="1" alt="" /&gt;</description></item></channel></rss>