Use PowerShell Workflow to Ping Computers in Parallel

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 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 his other guest blog posts.

Here’s the keyboard, Niklas.

The Test-Connection cmdlet is used to send ICMP echo request packets (“ping”) to one or more remote computers.

It’s a quick and easy way of finding out if computers are up and running.

To ping a single computer, you can simply type:

Test-Connection -ComputerName localhost

The Test-Connection cmdlet sends 4 echo requests by default. You can change this value to 1, telling the cmdlet to only perform 1 echo request.

Test-Connection -ComputerName localhost -Count 1

Pinging a computer that’s not on the network results in an error:

Test-Connection -ComputerName blablabla -Count 1

Test-Connection : Testing connection to computer ‘blablabla’ failed: No such ho

st is known

At line:1 char:1

+ Test-Connection -ComputerName blablabla -Count 1

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (blablabla:String) [Test-Co

   nnection], PingException

    + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Com

   mands.TestConnectionCommand

If you don’t want to display the error message, you can set the cmdlets ErrorAction to SilentlyContinue (or use a Try/Catch block and handle the error):

Test-Connection -ComputerName blablabla -Count 1 -ErrorAction SilentlyContinue

The error still occurs—it’s just not visible on the screen. (You can still access the error by typing $error[0].)

Now for some fun, let’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 Get-ADComputer cmdlet.

$computers = Get-ADComputer -Filter * | Select -ExpandProperty DNSHostName

Next, let’s see how many computers are in the domain:

$computers.Count

162

If you want to perform a ping test on each computer in the domain, you could type:

foreach ($computer in $computers) {

  Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue

}

The 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.

Let’s find out how much time the command takes by using Measure-Command:

Measure-Command -Expression {

  foreach ($computer in $computers) {

    Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue

  }

}

 

Days              : 0

Hours             : 0

Minutes           : 0

Seconds           : 39

Milliseconds      : 679

Ticks             : 396797893

TotalDays         : 0,000459256820601852

TotalHours        : 0,0110221636944444

TotalMinutes      : 0,661329821666667

TotalSeconds      : 39,6797893

TotalMilliseconds : 39679,7893

Notice how it takes 39 seconds to ping each computer on the network.

To speed things up, you can place the code in a Windows PowerShell workflow and benefit from the foreach -parallel language construct. Foreach -parallel allows you to process the computers in parallel.

workflow Test-WFConnection {

  param(

    [string[]]$Computers

  )

  foreach -parallel ($computer in $computers) {

    Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue

  }

}

 

Let’s see how long the workflow takes to execute:

Measure-Command -Expression { Test-WFConnection -Computers $computers }

Days              : 0

Hours             : 0

Minutes           : 0

Seconds           : 7

Milliseconds      : 808

Ticks             : 78082448

TotalDays         : 9,03732037037037E-05

TotalHours        : 0,00216895688888889

TotalMinutes      : 0,130137413333333

TotalSeconds      : 7,8082448

TotalMilliseconds : 7808,2448

And we are down at 7 seconds. Isn’t that cool!

~Niklas

Thank you, Niklas, for a great post that introduces the capability of Windows PowerShell workflow!

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy