【问题标题】:Wait until all threads complete before running next task等到所有线程完成后再运行下一个任务
【发布时间】:2017-07-18 16:08:03
【问题描述】:

我会将 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

【问题讨论】:

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

标签: multithreading powershell jobs start-job


【解决方案1】:

在执行ConvertTo-Json之前使用Get-Job | Wait-Job

【讨论】:

  • foreach 将创建 X 个作业(取决于 $computers 的长度。我以为 Wait-Job 只等待其中一个?
  • @KolobCanyon 也许单独使用,但不能与Get-Job 结合使用,因为这会将正在运行的作业传递给它:-)。查看链接文档中的示例 1。
【解决方案2】:

如何使用计算机名称数组作为Invoke-Command 的参数。默认情况下,它将运行 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    相关资源
    最近更新 更多