如果耗时太长,如何修改PowerShell作业的输出

时间:2019-07-09 22:26:17

标签: powershell jobs

我有一个相对较长/复杂的脚本,该脚本针对多个设备(作为作业)盲目运行了一批命令。有时,其中一些作业会无限期地继续运行。我已在脚本中添加了 Wait-Job -Timeout 命令(请参见下文),以强制停止耗时太长的作业。

我想将这些挂起作业的输出更改为“此设备正忙或不稳定” 。有人可以告诉我该怎么做吗?我猜我需要在管道的末尾添加一些内容(在下面的代码的最后一行中)。

$Jobs += Get-Job
$jobs | Wait-Job -Timeout 5 | out-null  

Get-Job | ? {$_.State -eq 'Running'} | Stop-Job -PassThru 

1 个答案:

答案 0 :(得分:3)

一种方法是遍历当前正在运行的作业,并为每个作业编写消息:

$Jobs += Get-Job
$Jobs | Wait-Job -Timeout 5 | Out-Null

Get-Job | ? { $_.State -eq 'Running' } | Stop-Job -PassThru | % { Write-Host "This device is busy or unstable" }

您还可以从正在停止的作业中添加信息,例如作业ID:

Get-Job | ? { $_.State -eq 'Running' } | Stop-Job -PassThru | % { Write-Host "This device is busy or unstable: $($_.Id)" }

更新:您可以使用哈希表存储“强制停止”的作业ID。然后使用Receive-Job遍历Jobs以获取输出,并检查Jobs是否在ForceStoppedIds表中。如果是,请编写您的自定义消息,否则仅输出消息。这是我运行的一个简单测试。

Start-Job -ScriptBlock { Write-Output "Starting 1."; Start-Sleep -Seconds 3; Write-Output "1 complete."; } | Out-Null
Start-Job -ScriptBlock { Write-Output "Starting 2."; Start-Sleep -Seconds 60; Write-Output "2 complete."; } | Out-Null
Start-Job -ScriptBlock { Write-Output "Starting 3."; Start-Sleep -Seconds 2; Write-Output "3 complete."; } | Out-Null
$Jobs += Get-Job
$Jobs | Wait-Job -Timeout 5 | Out-Null
$ForceStoppedIds = @{}
$Jobs | ? { $_.State -eq 'Running' } | Stop-Job -PassThru | % { $ForceStoppedIds[$_.Id] = $true }
foreach ($job in $Jobs) {
    $jobOutput = Receive-Job $job -Wait
    if ($ForceStoppedIds.Contains($job.Id)) {
        Write-Host "Custom message about stopped job: $($jobOutput)"
    }
    else {
        Write-Host $jobOutput
    }
}

要注意的一件事是作业如何输出信息(即Write-Host,Write-Output,Return等)。如果没有得到预期的结果,请仔细检查作业的ScriptBlock,以查看如何写入/返回/等信息。我敢肯定有很多更优雅的方法可以做到这一点,但是希望这会有所帮助。