并非所有PowerShell v2作业都可以运行

时间:2012-06-16 10:04:40

标签: powershell jobs

我正在尝试使用作业同时运行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

编辑:此外,由于我正在使用start-process powershell所有脚本同时运行(除非我启用-wait),而不需要start-job。我想用工作让我可以节流。也许这是错误的逻辑,我有一份工作开始一个新的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

我必须编辑我的所有脚本,以便我可以将参数作为参数传递,但现在一切正常。这个主题很有用Running multiple scriptblocks at the same time with Start-Job (instead of looping)

1 个答案:

答案 0 :(得分:0)

我的猜测是(在查看您的代码之后)是您将只获得前4个工作。 工作(甚至完成)不会自动消失。完成后需要清理它们(可能是第一次接收 - 作业)。如果你不这样做 - PowerShell将转移$ jobsMax工作,一旦完成 - 我会很惊讶地看到任何其他“新手”。

添加一些接收/删除作业逻辑,它应该更好。

另外:据我所知,你正在运行脚本,所以我建议在powershell.exe而不是-command上使用-File参数。

HTH 鲍尔泰克