Wait for a looping of jobs to finish and do something

Hello, Guys!

I hope you all are well.

I’m writing a script that create a loop of Remote Jobs to find Microsoft Office products on the network, however i’m struggling to write a logic that wait all the jobs to finish and then work with the output. Can someone help me to see what is wrong please?

[pre]

Function Get-officeDatacenter {
Param(
[String[]]$Servers
)
$limite = 500
$Output =@()
Foreach ($s in $servers) {
$check = $false
while ($check -eq $false){
if((get-job).count -lt $limite) {
Invoke-Command -ComputerName $s -ScriptBlock { Get-WmiObject Win32_Product |
Where-Object {($.Name -like “Microsoft Office*”) -and ($.Name -notlike “MUI”)} |
Select-Object Name, Version} -AsJob
$check = $true
}
}

}
If ($jobs.count -eq $Servers.Count) {
$Jobs = Get-Job
Foreach ($j in $Jobs.id) {
$detectedOffices = Receive-Job $j -Keep | Select-Object PsComputerName, Name, Version
$Output = $Output += $detectedOffices
}
}

}

[/pre]

 

 

Well, You Can do it like below.

$JobList = Invoke-Command -ComputerName $Servers -ScriptBlock { Get-Package -ProviderName Programs } -AsJob
$JobList | Wait-Job
$JobList | Receive-Job | Select-Object -Property Name, Version

Thank you, kvprasson for your aswer!

 

But the way that you wrote, i’m going to create only one job. What i would like to do is creating 1 job per server and defining a limit in a variable.

 

But your param block shows, [String[]]$Servers, which is a array …

Param
(
    [String[]]$Servers
)

… so, just passing in the server list.

So, what kvprasson is showing you is just using what you provided. Other than that, you could pipe or use a loop.

Some notes about Win32_Product: https://blogs.technet.microsoft.com/heyscriptingguy/2013/11/15/use-powershell-to-find-installed-software/

Regarding very basic throttling… This might do it:

while((Get-Job).Where({ $_.State -eq 'Running' }).Count -gt $limite) {
    Start-Sleep -Milliseconds 5 # less stress on cpu
}

And when all servers have been processed, wait for jobs to be done:

while((Get-Job).Where({ $_.State -eq 'Running' }).Count -gt 0) {
    Start-Sleep -Milliseconds 5 # less stress on cpu
}