{"id":4639,"date":"2012-11-20T00:01:00","date_gmt":"2012-11-20T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2012\/11\/20\/use-powershell-workflow-to-ping-computers-in-parallel\/"},"modified":"2012-11-20T00:01:00","modified_gmt":"2012-11-20T00:01:00","slug":"use-powershell-workflow-to-ping-computers-in-parallel","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-workflow-to-ping-computers-in-parallel\/","title":{"rendered":"Use PowerShell Workflow to Ping Computers in Parallel"},"content":{"rendered":"<p><strong>Summary:<\/strong> Guest blogger and Microsoft MVP Niklas Goude talks about using Windows PowerShell workflow to ping computers in parallel and save time.\nMicrosoft Scripting Guy, Ed Wilson, is here. Yesterday was an awesome time spent in Stockholm and the User group there. The Scripting wife and I had a great time with Niklas Goude and friends. So, it seems like a good day to host a guest blog written by none other than MVP Niklas Goude. Read more about Niklas and <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/niklas+goude\/\" target=\"_blank\">his other guest blog posts<\/a>.\nHere&rsquo;s the keyboard, Niklas.\nThe <strong>Test-Connection<\/strong> cmdlet is used to send ICMP echo request packets (&#8220;ping&#8221;) to one or more remote computers.\nIt&#8217;s a quick and easy way of finding out if computers are up and running.\nTo ping a single computer, you can simply type:<\/p>\n<p style=\"padding-left: 30px\">Test-Connection -ComputerName localhost\nThe <strong>Test-Connection<\/strong> cmdlet sends 4 echo requests by default. You can change this value to 1, telling the cmdlet to only perform 1 echo request.<\/p>\n<p style=\"padding-left: 30px\">Test-Connection -ComputerName localhost -Count 1\nPinging a computer that&#8217;s not on the network results in an error:<\/p>\n<p style=\"padding-left: 30px\">Test-Connection -ComputerName blablabla -Count 1<\/p>\n<p style=\"padding-left: 30px\">Test-Connection : Testing connection to computer &#8216;blablabla&#8217; failed: No such ho<\/p>\n<p style=\"padding-left: 30px\">st is known<\/p>\n<p style=\"padding-left: 30px\">At line:1 char:1<\/p>\n<p style=\"padding-left: 30px\">+ Test-Connection -ComputerName blablabla -Count 1<\/p>\n<p style=\"padding-left: 30px\">+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ResourceUnavailable: (blablabla:String) [Test-Co<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; nnection], PingException<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Com<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; mands.TestConnectionCommand\nIf you don&#8217;t want to display the error message, you can set the cmdlets <strong>ErrorAction<\/strong> to <strong>SilentlyContinue<\/strong> (or use a Try\/Catch block and handle the error):<\/p>\n<p style=\"padding-left: 30px\">Test-Connection -ComputerName blablabla -Count 1 -ErrorAction SilentlyContinue\nThe error still occurs&mdash;it&#8217;s just not visible on the screen. (You can still access the error by typing $error[0].)\nNow for some fun, let&#8217;s say that you want to test the connection to all computers in a domain. First, you get a list of all computers by using the <strong>Get-ADComputer<\/strong> cmdlet.<\/p>\n<p style=\"padding-left: 30px\">$computers = Get-ADComputer -Filter * | Select -ExpandProperty DNSHostName\nNext, let&#8217;s see how many computers are in the domain:<\/p>\n<p style=\"padding-left: 30px\">$computers.Count<\/p>\n<p style=\"padding-left: 30px\">162\nIf you want to perform a ping test on each computer in the domain, you could type:<\/p>\n<p style=\"padding-left: 30px\">foreach ($computer in $computers) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp; Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue<\/p>\n<p style=\"padding-left: 30px\">}\nThe command returns information from the computers that can be contacted. The only problem with this command is that it takes a lot of time because it pings one computer, and then waits for it to reply before pinging the next one.\nLet&#8217;s find out how much time the command takes by using <strong>Measure-Command<\/strong>:<\/p>\n<p style=\"padding-left: 30px\">Measure-Command -Expression {<\/p>\n<p style=\"padding-left: 30px\">&nbsp; foreach ($computer in $computers) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue<\/p>\n<p style=\"padding-left: 30px\">&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 39<\/p>\n<p style=\"padding-left: 30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 679<\/p>\n<p style=\"padding-left: 30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 396797893<\/p>\n<p style=\"padding-left: 30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,000459256820601852<\/p>\n<p style=\"padding-left: 30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,0110221636944444<\/p>\n<p style=\"padding-left: 30px\">TotalMinutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,661329821666667<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 39,6797893<\/p>\n<p style=\"padding-left: 30px\">TotalMilliseconds : 39679,7893\nNotice how it takes 39 seconds to ping each computer on the network.\nTo speed things up, you can place the code in a Windows PowerShell workflow and benefit from the <strong>foreach -parallel<\/strong> language construct. <strong>Foreach -parallel<\/strong> allows you to process the computers in parallel.<\/p>\n<p style=\"padding-left: 30px\">workflow Test-WFConnection {<\/p>\n<p style=\"padding-left: 30px\">&nbsp; param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; [string[]]$Computers<\/p>\n<p style=\"padding-left: 30px\">&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp; foreach -parallel ($computer in $computers) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue<\/p>\n<p style=\"padding-left: 30px\">&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">}\n&nbsp;\nLet&#8217;s see how long the workflow takes to execute:<\/p>\n<p style=\"padding-left: 30px\">Measure-Command -Expression { Test-WFConnection -Computers $computers }<\/p>\n<p style=\"padding-left: 30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 7<\/p>\n<p style=\"padding-left: 30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 808<\/p>\n<p style=\"padding-left: 30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 78082448<\/p>\n<p style=\"padding-left: 30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 9,03732037037037E-05<\/p>\n<p style=\"padding-left: 30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,00216895688888889<\/p>\n<p style=\"padding-left: 30px\">TotalMinutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,130137413333333<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 7,8082448<\/p>\n<p style=\"padding-left: 30px\">TotalMilliseconds : 7808,2448\nAnd we are down at 7 seconds. Isn&#8217;t that cool!\n~Niklas\nThank you, Niklas, for a great post that introduces the capability of Windows PowerShell workflow!\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.\n<strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Guest blogger and Microsoft MVP Niklas Goude talks about using Windows PowerShell workflow to ping computers in parallel and save time. Microsoft Scripting Guy, Ed Wilson, is here. Yesterday was an awesome time spent in Stockholm and the User group there. The Scripting wife and I had a great time with Niklas Goude and [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,183,362,3,4,45,382],"class_list":["post-4639","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-niklas-goude","tag-powershell-3","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell","tag-workflow"],"acf":[],"blog_post_summary":"<p>Summary: Guest blogger and Microsoft MVP Niklas Goude talks about using Windows PowerShell workflow to ping computers in parallel and save time. Microsoft Scripting Guy, Ed Wilson, is here. Yesterday was an awesome time spent in Stockholm and the User group there. The Scripting wife and I had a great time with Niklas Goude and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4639","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=4639"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4639\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=4639"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=4639"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=4639"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}