DOC / 1545 lazyadmin.nl

Ошибки в PowerShell: try/catch/finally, ErrorAction и результат задания

Красная строка в консоли ещё не означает, что задание завершилось с ошибкой. Некоторые ошибки PowerShell нетерминирующие, а внешний процесс может вернуть ненулевой exit code без исключения. Административному сценарию нужна явная модель успеха, остановки и очистки ресурсов.

Завершающие и незавершающие ошибки

try/catch реагирует на terminating errors. Командлет может сообщить ошибку и продолжить выполнение, поэтому для критического шага задают -ErrorAction Stop. Это превращает поддерживаемую незавершающую ошибку в ошибку, которую перехватит catch.

try {
    $config = Get-Content -LiteralPath '.\config.json' -Raw -ErrorAction Stop |
        ConvertFrom-Json -ErrorAction Stop
    if (-not $config.Environment) { throw 'В конфигурации нет Environment.' }
    $config
}
catch {
    Write-Warning ('Конфигурация не прочитана: {0}' -f $_.Exception.Message)
    throw
}

Последний throw повторно передаёт ошибку вызывающему коду. Если catch только выводит сообщение и завершается нормально, внешний планировщик может принять этот запуск за успешный.

Локальная политика вместо неожиданного глобального эффекта

Для короткого самостоятельного сценария можно установить $ErrorActionPreference = 'Stop'. В библиотечной функции обычно разумнее явно указать ErrorAction критическим командам. Не меняйте чужую глобальную настройку и не оставляйте её изменённой после выхода из функции.

Внутри catch $_ содержит ErrorRecord. Записывайте тип операции, идентификатор задания и безопасное сообщение, но не целиком входной объект с паролем, заголовки Authorization или результат установки ключа продукта.

Очистка в finally

$stream = $null
try {
    $stream = [IO.File]::OpenRead((Join-Path $PWD 'config.json'))
    [pscustomobject]@{ Bytes = $stream.Length }
}
catch {
    throw
}
finally {
    if ($null -ne $stream) { $stream.Dispose() }
}

finally используется для освобождения открытого ресурса независимо от успешного прохода или обычного исключения. Он не является гарантией при аварийном уничтожении процесса или отключении питания. Долговременное состояние задания нужно хранить отдельно.

Ошибка очистки тоже может скрыть первоначальную причину. Если очистка сложная, разделите её результат и исходный ErrorRecord и решите, какую ошибку передавать дальше.

Внешние программы проверяются отдельно

# Пример Windows: внешняя программа намеренно возвращает 7.
& "$env:SystemRoot\System32\cmd.exe" /c 'exit 7'
$code = $LASTEXITCODE
if ($code -ne 0) {
    throw "Внешняя программа завершилась с кодом $code"
}

Считывайте LASTEXITCODE сразу после нужного процесса. Для каждой программы проверьте собственное значение кодов: например, ненулевые коды некоторых утилит не всегда означают полный провал. Не переносите правило «всё кроме нуля — ошибка» на инструмент без чтения его контракта.

Вернуть правильный статус планировщику

# Оболочка отдельного файла задания, а не библиотечная функция.
try {
    # Здесь вызов вашей проверяемой операции.
    Get-Content -LiteralPath '.\config.json' -ErrorAction Stop | Out-Null
    exit 0
}
catch {
    Write-Error $_
    exit 1
}

exit завершает процесс оболочки, поэтому не используйте его глубоко внутри общей функции или модуля. Внутренние функции возвращают объект либо выбрасывают ошибку; граница задания переводит это в код завершения.

Набор проверок

Проверьте корректный файл, отсутствие файла, ошибочный JSON, отказ в доступе и внешний ненулевой код. Отдельно проверьте, что после исключения файловый дескриптор освобождён. Ошибка в одном объекте большого набора может либо остановить всё задание, либо сохранить отдельный failed-результат и продолжить — выберите и задокументируйте эту модель заранее.

Повторная попытка не является универсальным обработчиком. Неверный JSON и отсутствие разрешения нужно исправить; временную недоступность сети можно повторять ограниченно, если операция безопасна для повтора.

Документация: try/catch/finally, ErrorAction, LASTEXITCODE.

Иллюстрации к инструкции

Пример перехвата ошибки PowerShell.
Пример перехвата ошибки PowerShell.
Пример обработки исключения в исходном материале.
Пример обработки исключения в исходном материале.

Материал подготовлен самостоятельно на русском языке. Исходная тема и иллюстрации: LazyAdmin. Технические сведения сверены с документацией, указанной выше, 11 октября 2026 года. Интерфейсы и версии модулей могут отличаться от показанных примеров.

ORIGINAL / ATTRIBUTION

Источник материала

Материал переработан для SYSADM.VIP. Оригинальный источник указан ниже.

Оригинал статьи на lazyadmin.nl ↗

https://lazyadmin.nl/powershell/try-catch-finally/

Материал проверен 11.10.2026. При изменении программного обеспечения сверяйтесь с актуальной документацией.
← Вернуться в базу знаний