Help with a background job in Powershell

Hey all,

I just need some help getting my script to work. What my script does is connects to a bunch of computers on the domain and retrives a value out of their registry to make sure it is set correctly. I have about 3000 machines to loop through and all of them are spread out accross the nation. Looping through these one at a time takes forever because of the latency. What I would like to do is kick off this registry read for each computer as it's own background job so more than one can run at a time. The problem is I cannot find any examples of how to start multiple jobs and retreive their output etc. Im guessing I would have to create an array of jobs??? It probably also would be better to only run maybe 10 at a time or the processor will be hammered? Anybody have any experience with this?

Here is what I have so far but cannot quite seem to get it to work:

Function Get-Registry($Computer) {

      Trap { $Output = "$computer an error occured!"; return $Output  }  
      $Output = "" 
      $ping = New-Object System.Net.Networkinformation.Ping
      $Result = $ping.send($Computer)
      if (!($Result.status -eq "success")) { $Output = "$computer is offline!"; return $Output  }
      $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
      $Key = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
      $RegKey = $Reg.opensubkey($Key)

      foreach($val in $RegKey.getvaluenames()) {
            if ($val.tolower() -eq "uihost") {
                  $Temp = $RegKey.getvalue("$val")
                  if ($Temp.tolower() -like "logonui.exe" -or $Temp.tolower() -like "c:\windows\system32\logonui.exe") {
                        $Output = "$Computer is set correctly! UIHost = $Temp"
                        return $Output
                  } else {
                        $Output = "$Computer is not set correctly! UIHost = $temp"
                        return $Output

foreach ($computer in $script:computers) {
      Write-Host -NoNewline -ForegroundColor white "Scanning: " 
      Write-Host -ForegroundColor cyan $computer.tolower()
      $Job = Start-Job -ScriptBlock { Get-Registry $Computer }  
                     Receive-job $Job

I need to be able to take the output from my function and write it to a file....preferrably the same file and just have it appended.


Who is Participating?
soostibiConnect With a Mentor Commented:
I would do something like this:
$computernames = $script:computers
$script = {
	  $reg = get-itemproperty "hklm:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
	  if($reg.uihost -match "logonui\.exe"){
	  	"$($env:computername) is set correctly! UIHost = $($reg.uihost)"
	  else {
	  	"$($env:computername) is not set correctly! UIHost = $($reg.uihost)"

$computernames | %{
	if(Test-Connection -ComputerName $_ -Quiet){
		Invoke-Command -ComputerName $_ -ScriptBlock $script -AsJob
		"$_ is offline!"

while($jobs = Get-Job)
		{$_.state -eq "Completed"}{
			Receive-Job $_
			Remove-Job $_
		{$_.state -eq "Failed"}{
			"Job for computer $($_.location) has failed"
			Remove-Job $_
	Start-Sleep 5
} | Out-File -Append c:\yourpath\yourfile.txt

Open in new window

I would make it a login script and then force reboot each machine.....
Just to make sure I understand what you trying to accomlish..
You want to run multiple instances of your script, each instance pulling results from a different machine?

If that is the case, let me know, I have a few scripts that do this already.
For collecting results, have each instance 'add-content' to a logfile. Or, to ensure stability, have each instance right output to its OWN logfile, and at the end of the process, another script to get-content from each log file and add it to a master logfile and delete the various singles.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.