概览
希望调用一个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
我目前看到的内容:
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
23 Job23 Running True localhost #patch server ...
25 Job25 Running True localhost #patch server ...
我想看到的是:
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
我希望能够看到输出或将其存储在某个地方,以便我可以回头查看以确保脚本运行并查看哪些服务器重新启动等。
结论:
在过去,我运行脚本,它经历了更新服务器一次一个,并给我我想要的输出,但当我开始做更多的服务器-这个任务太长了,这就是为什么我试图使用后台作业与“启动作业”。
有人能帮我解决这个问题吗?
6条答案
按热度按时间czq61nw11#
你可以看看模块SplitPipeline。它是专门为这类任务设计的。工作演示代码是:
对于您的任务,用对脚本的调用替换
"processing server $_"; sleep 1
(模拟一个缓慢的作业),并使用变量$_
作为输入,即当前服务器。如果每个作业不是处理器密集型作业,则增加参数
Count
(默认值为处理器计数)以提高性能。lokaqttq2#
这不是一个新的问题,但我觉得它缺少一个答案,包括Powershell使用工作流及其并行的可能性,从Powershell版本3。这是更少的代码,也许更容易理解比开始和等待工作,这当然工作得很好。
我有两个文件:协调服务器的
TheScript.ps1
和进行某种检查的BackgroundJob.ps1
。它们需要在同一个目录中。后台作业文件中的
Write-Output
写入到启动TheScript.ps1
时看到的同一个流中。TheScript.ps1:
背景作业.ps1(例如):
因此,当启动
TheScript.ps1
时,它将写入“Processing server”3次,但它不会等待15秒,而是等待5秒,因为它们是并行运行的。7vhp5slm3#
在
ForEach
循环中,您将需要获取已运行的作业生成的输出。未测试示例
现在,如果你这样做,你的所有结果将是混合的。你可能想在你的详细输出上加一个戳来告诉你哪个输出来自。
或者
它将显示所有的输出,只要一个工作完成。没有被混淆。
6ioyuze24#
如果您希望处理多个正在进行的作业,您可能需要处理输出,以帮助在控制台上保持输出与作业直接相关。
pgccezyw5#
您可以在收到所有作业后执行以下操作来获得结果:
$array=@()获取作业名称 *| 其中{$array+=$_.子作业.输出}
.ChildJobs.输出将包含每个作业中返回任何内容
2mbi3lxu6#