【问题标题】:start-job Run command in parallel and output result as they arrivestart-job 并行运行命令并在结果到达时输出
【发布时间】:2013-03-27 23:25:57
【问题描述】:

我正在尝试在服务器列表中获取特定的 KBXXXXXX 存在,但是一旦我的脚本在一台服务器上运行,它需要时间并返回结果并返回然后移动到下一台。这个脚本对我来说非常好。 我希望我的脚本作为工作和其他进程启动并获取修补程序,只是为了收集结果并显示它们。

$servers = gc .\list.txt 
foreach ($server in $servers) 
{ 
    $isPatched = (Get-HotFix -ComputerName $server | where HotFixID -eq 'KBxxxxxxx') -ne $null 
    If ($isPatched) 
    { 
    write-host $server + "Exist">> .\patchlist.txt} 
    Else  
    { 
    Write-host $server +"Missing"
$server  >> C:\output.txt
    } 

}

它的目标是使列表执行得更快而不是连续运行。

【问题讨论】:

标签: powershell parallel-processing start-job


【解决方案1】:

使用 Powershell V2,您可以使用 @Andy 回答中的作业,也可以在此链接 Can Powershell Run Commands in Parallel? 中更详细地使用作业

使用 PowerShell V2,您可能还想使用运行空间查看此脚本 http://gallery.technet.microsoft.com/scriptcenter/Foreach-Parallel-Parallel-a8f3d22b

使用 PowerShell V3,您可以使用 foreach -parallel 选项。

例如(NB Measure-Command 只是用于计时,因此您可以进行比较)

Workflow Test-My-WF {  
  param([string[]]$servers)

  foreach -parallel ($server in $servers) {

    $isPatched = (Get-HotFix -ComputerName $server | where {$_.HotFixID -eq 'KB9s82018'}) -ne $null     
    If ($isPatched) 
    { 
        $server | Out-File -FilePath "c:\temp\_patchlist.txt" -Append
    } 
    Else  
    { 
        $server | Out-File -FilePath "c:\temp\_output.txt" -Append 
    } 
  }
}

Measure-Command -Expression { Test-My-WF   $servers }

【讨论】:

    【解决方案2】:

    为此使用 PowerShell 作业。

    小命令:

    • 找工作
    • 接收作业
    • 删除作业
    • 开始工作
    • 停止工作
    • 等待工作

    这是一个未经测试的例子:

    $check_hotfix = {
        param ($server)
        $is_patched = (Get-HotFix -ID 'KBxxxxxxx' -ComputerName $server) -ne $null 
        if ($is_patched) { 
            Write-Output ($server + " Exist") 
        } else { 
            Write-Output ($server + " Missing")
        }
    }
    
    foreach ($server in $servers) {
        Start-Job -ScriptBlock $check_hotfix -ArgumentList $server | Out-Null
    }
    
    Get-Job | Wait-Job | Receive-Job | Set-Content patchlist.txt
    

    【讨论】:

      【解决方案3】:

      与其使用作业,不如使用 cmdlet 中内置的查询多台计算机的功能。 Microsoft 的许多 cmdlet,尤其是那些用于系统管理的 cmdlet,将字符串数组作为-Computername 参数的输入。传入您的服务器列表,cmdlet 将查询所有服务器。大多数具有此功能的 cmdlet 将串联查询服务器,但 Invoke-Command 将并行执行。

      我没有对此进行测试,因为我目前没有启动 Windows,但这应该可以帮助您开始(按顺序)。

      $servers = gc .\list.txt 
      $patchedServers = Get-HotFix -ComputerName $servers | where HotFixID -eq 'KBxxxxxxx'|select machinename
      
      $unpatchedServers = compare-object -referenceobject $patchedServers -differenceobject $servers -PassThru
      
      $unpatchedServers |out-file c:\missing.txt;
      $patchedServers|out-file c:\patched.txt;
      

      并行:

      $servers = gc .\list.txt 
      $patchedServers = invoke-command -computername $servers -scriptblock {Get-HotFix | where HotFixID -eq 'KBxxxxxxx'}|select -expandproperty pscomputername |sort -unique
      

      和以前一样,我目前没有合适的 Windows 版本来测试上述内容并检查输出,但这是一个起点。

      【讨论】:

      • @alroc 这很有趣,您能否链接到有关此类并行处理的一些在线文章。谢谢
      • @PaulRowland,不幸的是,我很难找到关于它“如何”工作的好文档。查看Get-Hotfix 和the first few hits here 的帮助。当你需要的时候工作很好,但它们会引入不必要的复杂性。使用 PowerShell 为您提供的功能 - MS 的并行性可能比您做得更好。
      • @alroc - 谢谢你,但我没有看到它建议它在哪里并行执行它们。知道它是否与使用 foreach -parallel 选项在幕后相同也会很有趣。我现在手头没有测试服务器,但我可以运行一个脚本来比较两者。
      • 以上代码对不同的服务器并行执行一系列相同的命令对加速进程没有任何好处。
      • 我已通过 Twitter 得到更正; invoke-command 并行运行,但其他 cmdlet 是顺序的(请参阅“从多台计算机检索 WMI 信息”部分 here)。您可以使用那里概述的技术来使用 Invoke-Command 来获得并行性,而无需求助于作业。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      相关资源
      最近更新 更多