Powershell:在parralel中运行多个作业,并查看后台作业的流式处理结果

tal*_*ule 15 parallel-processing powershell background-process start-job

概观

想要调用带有参数的Powershell脚本,在后台运行每个作业,并向我显示详细输出.

我遇到的问题

该脚本似乎正在运行,但我希望通过在后台作业运行时流式传输结果来确认这一点.

###StartServerUpdates.ps1 Script###

#get list of servers to update from text file and store in array
$servers=get-content c:\serverstoupdate.txt

#run all jobs, using multi-threading, in background
ForEach($server in $servers){
  Start-Job -FilePath c:\cefcu_it\psscripts\PSPatch.ps1 -ArgumentList $server
}

#Wait for all jobs
Get-Job | Wait-Job

#Get all job results
Get-Job | Receive-Job
Run Code Online (Sandbox Code Playgroud)

我目前看到的是:

Id              Name            State      HasMoreData     Location             Command                  
--              ----            -----      -----------     --------             -------                  
23              Job23           Running    True            localhost            #patch server ...        
25              Job25           Running    True            localhost            #patch server ...        
Run Code Online (Sandbox Code Playgroud)

我想看到的:

Searching for approved updates ...

Update Found:  Security Update for Windows Server 2003 (KB2807986)
Update Found:  Windows Malicious Software Removal Tool - March 2013 (KB890830)

Download complete.  Installing updates ...

The system must be rebooted to complete installation.
cscript exited on "myServer" with error code 3.
Reboot required...
Waiting for server to reboot (35)

Searching for approved updates ...

There are no updates to install.
cscript exited on "myServer" with error code 2.
Servername "myServer" is fully patched after 2 loops
Run Code Online (Sandbox Code Playgroud)

我希望能够在某处看到输出或存储,以便我可以参考以确保脚本运行并查看重新启动的服务器等.

结论:

在过去,我运行脚本,它一次一个地更新服务器,并给了我想要的输出,但是当我开始做更多的服务器时 - 这个任务花了太长时间,这就是我尝试使用背景的原因"Start-Job"工作.

有人能帮我解决这个问题吗?

Rom*_*min 6

您可以查看SplitPipeline模块.它专门为这些任务而设计.工作演示代码是:

# import the module (not necessary in PS V3)
Import-Module SplitPipeline

# some servers (from 1 to 10 for the test)
$servers = 1..10

# process servers by parallel pipelines and output results immediately
$servers | Split-Pipeline {process{"processing server $_"; sleep 1}} -Load 1, 1
Run Code Online (Sandbox Code Playgroud)

对于您的任务替换"processing server $_"; sleep 1(模拟一个慢作业)调用您的脚本并使用该变量$_作为输入,当前服务器.

如果每个作业不是处理器密集型,则增加参数Count(默认为处理器计数)以提高性能.


小智 5

这不是一个新问题,但是我觉得它缺少一个答案,包括Powershell版本3中使用工作流的Powershell及其并行可能性。这比启动和等待作业少了代码,也许更容易理解,当然也很好。

我有两个文件:TheScript.ps1协调服务器和BackgroundJob.ps1进行某种检查。它们需要在同一目录中。

Write-Output后台作业文件写入看到启动时相同的流TheScript.ps1

TheScript.ps1:

workflow parallelCheckServer {
    param ($Servers)
    foreach -parallel($Server in $Servers)
    {
        Invoke-Expression -Command ".\BackgroundJob.ps1 -Server $Server"
    }
}

parallelCheckServer -Servers @("host1.com", "host2.com", "host3.com")

Write-Output "Done with all servers."
Run Code Online (Sandbox Code Playgroud)

BackgroundJob.ps1(例如):

param (
    [Parameter(Mandatory=$true)] [string] $server
)

Write-Host "[$server]`t Processing server $server"
Start-Sleep -Seconds 5
Run Code Online (Sandbox Code Playgroud)

因此,启动TheScript.ps1时它将写入“ Processing server” 3次,但不会等待15秒,而是等待5秒,因为它们是并行运行的。

[host3.com]  Processing server host3.com
[host2.com]  Processing server host2.com
[host1.com]  Processing server host1.com
Done with all servers.
Run Code Online (Sandbox Code Playgroud)