等到所有线程完成后再运行下一任务

问题描述:

我会将foreach($computer in $computers)中的所有内容都包含在Start-Job中,以使它们同时运行。唯一的问题是,我需要等待所有的工作完成,然后才能完成底部的ConvertTo-Json等到所有线程完成后再运行下一任务

$sb = "OU=some,OU=ou,DC=some,DC=domain" 
$computers = Get-ADComputer -Filter {(Enabled -eq $true)} -SearchBase "$sb" -Properties * 
$hasmanufacturer = New-Object System.Collections.Generic.List[System.Object] 
foreach($computer in $computers) 
{ 
    $drives = try{@(Get-WMIObject -Class Win32_CDROMDrive -Property * -ComputerName $computer.Name -ErrorAction Stop)} catch {$null} 
    foreach($drive in $drives) 
    { 
     if($drive.Manufacturer) 
     { 
      $hasmanufacturer.Add($computer) 
      continue 
     } 
    } # inner foreach 
} 

ConvertTo-Json $hasmanufacturer 
+0

不相关,但是......为什么在出现错误时返回'$ null'时为了使用'-ErrorAction Stop'?删除'try..catch'和'@()'并使用'-ErrorAction SilentlyContinue'应该具有完全相同的效果。 –

执行ConvertTo-Json

+0

这个foreach将创建X个作业(取决于'$ computers'的长度,我认为'Wait-Job'只等待其中的一个? –

+0

@KolobCanyon也许是它自己的,但不能与'Get-Job '因为这将正在运行的工作传递给它:-)。查看链接文档中的示例1。 – gms0ulman

有关使用计算机名称数组作为参数Invoke-Command之前如何使用Get-Job | Wait-Job。默认情况下,它将运行32个并发远程会话。该数字可以通过-Throttle参数进行更改。

$computers = Get-ADComputer -Filter {(Enabled -eq $true)} -SearchBase "OU=Servers,DC=xxx,DC=com" -Properties Name | 
    Where-Object { $_.Name -match 'LAX_*' } | 
    ForEach-Object { $_.Name } 

$computers 

$j = Invoke-Command ` 
    -ComputerName $computers ` 
    -ScriptBlock { Get-WMIObject -Class Win32_CDROMDrive -Property * -ErrorAction Stop } ` 
    -AsJob 

while ((Get-Job -Id $j.Id).Status -eq 'Running') {} 

Get-Job -Id $j.Id | Wait-Job 

$results = Receive-Job -Id $j.Id 
$results