Learn about Windows PowerShell
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 {
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) {
Let's see how long the workflow takes to execute:
Measure-Command -Expression { Test-WFConnection -Computers $computers }
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
Great example of using a workflow...thanks for the idea!
@LA Richards yes, I was really impressed when Niklas sent the article. It is a great idea.
Playing around with this example and I noticed two things. First, I don't get any data back with either Test-Connection or Get-Wmiobject. And second, inside a workflow statement get-wmiobject wants me to use PSComputerName for remote connectivity. Is there something that discusses the why to both observations?
Ok, I found out what I did wrong. I wasn't calling the workflow anywhere in the script....oops. But, is there anyword on why workflow changes parameter names like -computername to -pscomputername?
@LA Richards Great question. PSComputername is a common workflow parameter. You can find more information in the PowerShell help topic about_WorkflowCommonParameters:
technet.microsoft.com/.../jj129719.aspx
Hi Niclas,
this is cool! Thanks for sharing it.
I had an approvement from 96.3 to 17.7 seconds (98 computers) which is a factor of 5.4 quite similar to your factor: 5!
I checked it again against 1000 computers: The parallel workflow solution took 196.5 seconds ( ~ 3 and a half minutes ) to run, which is quite acceptable and a time I could "actively wait" ( := go an get a coffee ) for results :-)
Executing the sequential approach gave me the results after a returned from lunch: 1016,1 seconds or 16,93 minutes
which is another factor 5,x
This is great and really easy to use, at least in this case!
Thanks, Klaus
Great Script, thanks everyone.
@K_Schulte wow ... thanks for the statistics ... pinging 1000 computers in 3 1/2 minutes is impressive indeed. Niklas hit a home run with this article.
This is perfect timing, I'm working on a script right now that this would be perfect for thanks!
A workflow consists of a sequence of concatenated (connected) steps. Emphasis is on the flow paradigm, where each step follows the precedent without delay or gap and ends just before the subsequent step may begin. This concept is related to non overlapping tasks of single resources.
bworkflow is a intuitive <a href=" http://www.bworkflow.com/> process improvement software </a> management software which help to increase <a href=" http://www.bworkflow.com/> business process improvement </a> operational improvement, site audit and operating compliance with business safety legislation
Great information and i like the way you write - thumbs up! networks360.net/.../it-support.html
You should also put "-ErrorAction SilentlyContinue" on the "Select" incase you have a computer object that does not have the DNSHostName populated like I did in my case.
$computers = Get-ADComputer -Filter * | Select -ExpandProperty DNSHostName -ErrorAction SilentlyContinue
sorry if this gets double posted
The facor of five seems to be a limit with workflow:
jeffwouters.nl/.../powershell-workflow-foreach-parallel-limited-to-5-parallel-threads