【问题标题】:Processing data returned from Invoke-Command as it's received?处理从 Invoke-Command 返回的数据?
【发布时间】:2016-05-09 21:07:10
【问题描述】:

我有一个要在 5,000 多个端点上运行的 PowerShell 脚本。该脚本枚举了有关每个主机的大量信息,然后我希望能够将这些信息提取到另一个程序中进行分析。

我遇到的问题是 Invoke-Command 不允许我处理从每台机器接收到的数据。这是一个问题,因为使用 5,000 多个端点时,我在运行 Invoke-Command 的机器上遇到了内存限制。

理想情况下,我希望能够在每次收到来自机器的响应时执行一个脚本块。类似这样的东西,例如:

$ProcessOutput = {
    # $_ = Data returned from one machine    
    $_ | Out-File ($_.PSComputerName)
}

Invoke-Command -FilePath $ScriptPath -ComputerName $Computers -ProcessingScriptBlock $ProcessOutput

这是否已经可能并且我忽略了一些东西?还是将我的计算机列表拆分为多个块并逐个扫描每个块(导致运行时间更长)的最佳解决方案?

【问题讨论】:

    标签: powershell powershell-remoting invoke-command


    【解决方案1】:

    您可以使用作业、foreach -parallel(在工作流中)或运行空间(比作业更快,但更复杂)来运行并行工作负载。这是一个使用作业的示例,最容易阅读。

    $ProcessOutput = {
        # $_ = Data returned from one machine    
        $_ | Out-File "$($_.PSComputerName).txt"
    }
    
    $Computers = "localhost", "frode-pc"
    
    #Start job
    $mainjob = Invoke-Command -FilePath $ScriptPath -ComputerName $Computers -AsJob
    
    #Process results as they complete
    while ($mainjob.State -eq "Running") {
        $mainjob.ChildJobs | Where-Object { $_.State -eq 'Completed' } | Receive-Job | ForEach-Object $ProcessOutput
    }
    
    #Process last job(s)
    $mainjob.ChildJobs | Where-Object { $_.State -eq 'Completed' } | Receive-Job | ForEach-Object $ProcessOutput
    

    如果性能至关重要,请使用运行空间。查看 Invoke-Parallel 了解易于使用的运行空间实现

    【讨论】:

    • Boe Prox created a great module called PoshRSJob 让您以类似于 PSJobs 的方式使用运行空间,但效果更好。
    • 会检查的。在我的答案中添加了Invoke-Parallel 作为运行空间解决方案。我通常使用自己自制的运行空间脚本模板手动执行此操作(我有几个使用不同的超时系统):-)
    猜你喜欢
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多