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?


Function Get-officeDatacenter {
$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





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 …


… 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: Use PowerShell to Find Installed Software - Scripting Blog

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