JohnF
 New Member Posts:12

 |
| 17 Jun 2009 09:37 AM |
|
Hello, I have a monitor script that pings each and every machine to see if it is up. The results are then spit out into a database. I'm currently using a foreach over all my machine names which is slow. I wanted to convert the script to using background jobs instead, so all of the machines can be checked simultaneously. I was wondering if I could get an explanation as to why it seems I can't pass information into start-job. Maybe I'm doing something wrong here but not sure. $computers = "server1","server2" foreach ($computer in $computers) { start-job {ping $computer} } The job status fails every time I run this. Another example: foreach ($computer in $computers) { start-job { ./ping.ps1 $computer } } ping.ps1 basically pings the computer and uses a redirect >> to a test.txt file Is it not possibly to pass something into start-job or should I be using the pipeline instead? Any suggestions on a better way to execute what I'm doing is welcome. Thanks |
|
|
|
|
Marco Shaw (MVP)
 Veteran Member Posts:1641

 |
| 17 Jun 2009 09:58 AM |
|
Try it like this: foreach($computer in $computers){invoke-expression "start-job {ping $computer}"} That seems to work for me. |
|
Marco
*Microsoft MVP - Windows PowerShell
https://mvp.support.microsoft.com/profile/Marco.Shaw
*Co-Author - Sams Windows PowerShell Unleashed 2nd Edition
*Blog - http://marcoshaw.blogspot.com |
|
|
Poshoholic PowerShell MVP, Community Director
 Basic Member Posts:110

 |
| 17 Jun 2009 10:32 AM |
|
Marco's got it right. You need to keep in mind that a background job you create is run in a new session. The new session doesn't load the profile and doesn't have access to variables in your current session, so $computer is null in the background job. To fix that you need to evaluate $computer first and create the background job using the results of $computer. That's what Marco's script does. |
|
Kirk Munro [MVP]
Poshoholic
My blog: http://poshoholic.com
Follow me on Twitter: http://twitter.com/poshoholic |
|
|
Shay Levy PowerShell MVP, Admin
 Veteran Member Posts:1362

 |
| 17 Jun 2009 10:46 AM |
|
Here's another approach, it creates one job (instead of one per computer) only and uses the builtin job functionality of the cmdlet: $job = Test-Connection -ComputerName $computers -AsJob You can also add the -ThrottleLimit parameter if you want to set the maximum number of concurrent connections that can be established to run this command. If you omit this parameter or enter a value of 0, the default value, 32, is used. To get the results: Receive-Job -job $job
|
|
Shay Levy Windows PowerShell MVP
http://PowerShay.com
PowerShell Community Toolbar
Twitter: @ShayLevy |
|
|
JohnF
 New Member Posts:12

 |
| 17 Jun 2009 12:04 PM |
|
Thanks for the quick responses. It seems that invoke-expression is what I was looking for. However I seem to still have issues with start-job. Powershell might have an issue with port 80 since I'm running a web server on this host. PS C:\> receive-job 121 Receive-Job : [localhost] Connecting to remote server failed with the following error message : The WinRM client sent a request to an HTTP server and got a response saying the requested HTTP URL was not available. This is usually returned by a HTTP server that does not support the WS-Management protocol. At line:1 char:12 + receive-job <<<< 121 + CategoryInfo : OpenError: (:) [Receive-Job], PSRemotingTransportException + FullyQualifiedErrorId : RemoteRunspaceStateBroken What is someone supposed to do if they want to run a web server on port 80 and powershell remoteing/background jobs? Thanks again |
|
|
|
|