Powershell некорректно обрабатывает коды выхода из запущенных нативных exe-файлов (не из командлетов).
Допустим у нас есть команда, которая запускает exe-файл и возвращает код отличный от 0 и мы хотим обработать эту ситуацию с помощью Try-Catch.
Вопреки интуитивному ожиданию такая конструкция не сработает:

try
{
  run_buggy_executive.exe
  run_somthing_else.exe
}
catch
{
  Wtite-Host "We got an error!!!"
}

Мы не получим сообщения We got an error!!! при ненулевом коде возврата из run_buggy_executive.exe, а запущены будут оба исполняемых файла (или команды). Как же быть?
Вариантов фактически два (https://stackoverflow.com/questions/9948517/how-to-stop-a-powershell-script-on-the-first-error):

  • Вручную проверять код выхода (код запуска и проверки можно обернуть в функцию, но фактически способ останется тем же):
    try
    {
      doSomething -arg myArg
      if (-not $?) { Write-Error -Message "doSomething Failed..." -ErrorAction Stop }
    }
    catch 
    {
      Write-Error -Message "We have a problem. $PSItem" -ErrorAction Stop
    }

    Тут важно обратить внимание на -ErrorAction Stop - без него будет просто отображение сообщения об ошибке, а не остановка.
    Ну или можно использовать throw вместо Write-Error -ErrorAction Stop

  • Второй вариант - гораздо более практичный, но очень неочевидный - это перенаправление stderr в stdout:

    try
    {
      doSomething -arg myArg 2>&1
    }
    catch 
    {
      Write-Error -Message "We have a problem. $PSItem" -ErrorAction Stop
    }

В итоге - при ошибке код в блоке Try остановится на строке, которая вызвала ошибку и дальше исполнится блок Catch.

Enter your comment. Wiki syntax is allowed:
 
  • ms_windows_ms_sql/powershell_exe_files_in_try_catch.txt
  • Last modified: 2021/05/25 10:45
  • by admin