Как мне проверить успешность / отказ конвейера из одного и того же исполняемого скрипта?
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. Код внутри блока «Попытка» автоматически переключится на «Перехват» в случае проблем, и, что еще лучше, вы можете иметь разные блоки перехвата для разных исключений, так что вы можете справляться с разными проблемами на лету. Очень круто.