Как изменить вывод заданий PowerShell, если они занимают слишком много времени - PullRequest
1 голос
/ 10 июля 2019

У меня относительно длинный / сложный скрипт, который вслепую запускает пакет команд для нескольких устройств (в качестве заданий). Однажды, некоторые из этих рабочих мест продолжают работать бесконечно. Я добавил команду Wait-Job -Timeout в свой сценарий (см. Ниже), чтобы принудительно остановить задания, выполнение которых занимает слишком много времени.

Я хотел бы изменить вывод этих зависших заданий на «Это устройство занято или нестабильно» . Может кто-нибудь сказать, пожалуйста, как это сделать? Я предполагаю, что мне нужно добавить что-то в конец конвейера (в последней строке кода ниже).

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

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

1 Ответ

3 голосов
/ 10 июля 2019

Один из способов - перебрать задания, которые в данный момент выполняются, и написать сообщение для каждого из них:

$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" }

Вы также можете добавить информацию о остановленных заданиях, например, идентификатор задания дляпример:

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

ОБНОВЛЕНИЕ: Вы можете использовать хеш-таблицу для хранения идентификаторов заданий, которые были «принудительно остановлены».Затем выполните перебор заданий, используя Receive-Job, чтобы получить выходные данные, и проверьте, находится ли задание в таблице 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 задания, чтобы увидеть, как информация записывается / возвращается / и т.д.Я уверен, что есть намного более изящные способы сделать это, но, надеюсь, это поможет.

...