我正在尝试使用作业来同时运行 PowerShell 实例,以便我的脚本可以更快地完成。我调用的脚本都是独立的,不需要互斥等。问题是它会调用 50 个脚本中的 5 个然后它会停止。其余的脚本似乎永远不会运行。等待工作有什么问题吗?同样由于某种原因,实际运行的五个脚本似乎被执行了两次,所以我得到了双倍的输出......
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
$ScriptDir = Split-Path $Invocation.MyCommand
$ScriptDir -match '(?<content>.*\d)' | out-null
$MainDir = $matches['content']
$ScriptName = $MyInvocation.MyCommand.Name
$Items = Get-ChildItem -Path $MainDir | Where-Object {$_.mode -match "d"}
$jobMax = 4
$jobs = @()
$jobWork = {
param ($MyInput,$dir)
$command = "$dir\" + $MyInput.name + "\" + $MyInput.name + ".ps1"
Start-Process powershell.exe -argumentlist $command -WindowStyle Hidden #-wait
}
foreach ($Item in $Items) {
if ($jobs.Count -le $jobMax) {
$jobs += Start-Job -ScriptBlock $jobWork -ArgumentList $Item,$MainDir
} else {
$jobs | Wait-Job -Any
}
}
$jobs | Wait-Job
编辑:另外,由于我使用的是启动进程 powershell,所有脚本同时运行(除非我启用 -wait),而不需要启动作业。我想使用工作,以便我可以节流。也许我有一份工作开始一个新的powershell实例是错误的逻辑?
Edit2:因为我认为使用 start-job 启动一个新的 poweshell 实例是错误的。这样,在打开新的 powershell 实例后工作就完成了,实际的脚本内容与工作的开始和结束无关。这是我的固定脚本:)
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
$ScriptDir = Split-Path $Invocation.MyCommand
$ScriptDir -match '(?<content>.*\d)' | out-null
$MainDir = $matches['content']
$ScriptName = $MyInvocation.MyCommand.Name
$Items = Get-ChildItem -Path $MainDir | Where-Object {$_.mode -match "d"}
$maxJobs = 4
$jobs = @()
foreach ($Item in $Items) {
$command = "$MainDir\" + $Item.name + "\" + $Item.name + ".ps1"
$jobs += Start-Job -filepath $command -ArgumentList $MainDir,$Item
$running = @($jobs | ? {$_.State -eq 'Running'})
while ($running.Count -ge $maxJobs) {
$finished = Wait-Job -Job $jobs -Any
$running = @($jobs | ? {$_.State -eq 'Running'})
}
}
Wait-Job -Job $jobs > $null
我必须编辑所有脚本,以便可以将参数作为参数传递,但现在一切正常。该线程很有帮助使用 Start-Job 同时运行多个脚本块(而不是循环)