我正在尝试同时在多台计算机上运行我拥有的 PowerShell 脚本。目前,我使用的是 PowerShell 版本 5。
我想知道是否可以在没有后台进程的情况下运行它,以便更好地理解日志。
$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"
$scriptBlock = {
param (
[string]$scriptPath
)
try {
# Execute the script
& $scriptPath
}
catch {
Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
}
}
foreach ($computer in $computers) {
Start-Job -ScriptBlock $scriptBlock -ArgumentList $scriptPath -Name $computer
}
while (Get-Job -State Running) {
Start-Sleep -Milliseconds 100
}
Get-Job | Receive-Job
Get-Job | Remove-Job
任何帮助都将不胜感激。
答案1
我认为您有三个选择:
- 继续做作业,但稍微重构一下代码
ForEach-Object -Parallel
在 PowerShell 7 中使用- 尝试使用工作流程在 PowerShell 5 中,允许
foreach -Parallel ($a in $x) {}
哪些是另一种令人头疼的问题
Invoke-Command
以下是用于创建作业并Wait-Job
等待作业的代码片段:
$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"
$scriptBlock = {
try {
& $Using:scriptPath
}
catch {
Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
}
}
$Jobs = Invoke-Command -ScriptBlock $scriptBlock -ComputerName $computers -AsJob
# Results (Logs) are stored in the $Result variable
$Result = $Jobs | Wait-Job | Receive-Job
$Jobs | Remove-Job
以下是你可以使用的方法ForEach-Object -Parallel
,但请注意,有时这并不让你像平常一样将东西输出到控制台,并且可能会给你带来其他麻烦:
#Requires -Version 7
$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"
$scriptBlock = {
try {
& $Using:scriptPath
}
catch {
Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
}
}
$computers | ForEach-Object -Parallel {
Invoke-Command -ScriptBlock $scriptBlock -ComputerName $_
}
我绝对建议继续使用 Jobs 并通过以下方式获取日志Receive-Job