Назад | Перейти на главную страницу

'статус выхода' конвейера PowerShell

Как мне проверить успешность / отказ конвейера из одного и того же исполняемого скрипта?

Get-VM -Name Machine | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-1)} | Remove-Snapshot -Confirm:$false

Мне не нужно ничего, кроме эквивалента $?.

Согласитесь с подходом try ... catch, но если ($?) {} тоже работает хорошо, но не отлавливает исключения, которые обычно полностью сбрасывают скрипт.

В любом случае, одна из сильных сторон PowerShell также является одной из ее слабых сторон. Я говорю о конвейерной обработке. Да, это здорово, что вы можете передавать объекты по конвейеру, но когда ваш скрипт запущен в производственной среде, и вам нужно аккуратно выйти из строя, создать значимый журнал, вернуть значимый код возврата, возможно, отправить SMS человеку в режиме ожидания и, возможно, даже запустить задание восстановления, конвейер, который только что отключил 50-й обнаруженный объект, когда осталось выполнить еще 70, не имеет особого смысла.

В производственном сценарии я настоятельно рекомендую поставить вашу «трубу». То есть используйте возможности конвейера, чтобы собрать вашу рабочую очередь (Get-VM | Where-Object, бла, бла) и поместить ее в массив объектов.

Затем используйте Foreach-Object для перехода по объектам в вашей рабочей очереди. В Foreach-Object используйте свой try ... catch, когда дело доходит до таких вещей, как Remove-Snapshot, и опросите возвращенный объект исключения, чтобы предоставить код возврата / файл журнала / последовательность предупреждений / восстановления и т. Д.

Как уже указывалось, безопасным подходом является использование блоков Try / Catch:

try
{
    Get-VM -Name Machine | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-1)} | Remove-Snapshot -Confirm:$false
}
catch
{
    # Rainbows, unicorns and error handling here
}

Если вы назначаете вывод переменной и хотите протестировать вывод самостоятельно, вы можете поместить блок try / catch в подвыражение и установить для него значение по умолчанию $null или $false при неудаче, вот так:

$results = $( try{Get-Something "MaybeNonexisting"} catch{$false} )

if(-not($results))
{
    # more unicorns
    Write-Host ("Something awful happened: {0}" -f $Error[0])
}

Ну, в Powershell есть $?, Поэтому я предполагаю, что проблема в том, что он заполняется только при выходе?

Когда вы имеете дело с ошибками в запущенном коде, лучше всего использовать Блокировка Try / Catch. Код внутри блока «Попытка» автоматически переключится на «Перехват» в случае проблем, и, что еще лучше, вы можете иметь разные блоки перехвата для разных исключений, так что вы можете справляться с разными проблемами на лету. Очень круто.