WindowsPowerShell

PowerShellのエラーハンドリング【try-catch-finally・$ErrorActionPreference・ログ出力】

WindowsPowerShell
記事内に広告が含まれています。

本番で動かすスクリプトには必ずエラーハンドリングが必要です。try-catch-finallyの使い方と、PowerShell固有のエラー制御の仕組みを解説します。

try-catch-finally

try {
    $content = Get-Content -Path "C:\missing.txt" -ErrorAction Stop
    Write-Host "読み込み成功: $($content.Count)行"
}
catch [System.IO.FileNotFoundException] {
    Write-Error "ファイルが見つかりません: $_"
}
catch [System.UnauthorizedAccessException] {
    Write-Error "アクセス権限がありません: $_"
}
catch {
    Write-Error "予期しないエラー: $($_.Exception.Message)"
    Write-Error "スタックトレース: $($_.ScriptStackTrace)"
}
finally {
    Write-Host "処理終了(エラーの有無に関わらず実行)"
}

-ErrorAction と $ErrorActionPreference

動作
Continue(デフォルト)エラーを表示して処理を続行
Stopエラーで例外を発生させる(try-catchで捕捉可能)
SilentlyContinueエラーを表示せず処理を続行
Inquireエラー時にユーザーに確認する
# コマンド単体に適用
Get-Item "C:\missing" -ErrorAction SilentlyContinue

# スクリプト全体に適用
$ErrorActionPreference = "Stop"

# $?:直前のコマンドが成功したか
Get-Process "notepad" -ErrorAction SilentlyContinue
if ($?) { Write-Host "メモ帳は実行中" } else { Write-Host "メモ帳は起動していない" }

# $LASTEXITCODE:外部コマンドの終了コード
python --version
if ($LASTEXITCODE -eq 0) { Write-Host "Pythonが使用可能" }

エラーログをファイルに記録する

function Write-Log {
    param(
        [string]$Message,
        [ValidateSet("INFO","WARN","ERROR")]
        [string]$Level = "INFO"
    )
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logLine = "[$timestamp] [$Level] $Message"
    Add-Content -Path "C:\logs\script.log" -Value $logLine -Encoding UTF8
    if ($Level -eq "ERROR") { Write-Error $Message }
    else { Write-Host $logLine }
}

try {
    Write-Log "処理開始"
    # 何らかの処理
    Write-Log "処理完了"
} catch {
    Write-Log "エラー発生: $($_.Exception.Message)" -Level "ERROR"
}

スクリプトにtry-catchを入れるのは「エラーが起きないように」ではなく「エラーが起きたときに何をするかを決めるため」です。特に本番環境で動かすバッチ処理では、エラーをログに残して管理者に通知する仕組みまで含めて設計することが重要です。

hobbyshift管理人

まとめ

  • try-catch-finallyでエラーを安全に処理できる
  • -ErrorAction Stopをつけることでcatchでエラーを捕捉できるようになる
  • $?で直前のコマンドの成否、$LASTEXITCODE外部コマンドの終了コードを確認できる
  • Write-Log関数を作ってすべてのスクリプトで使い回すのがベストプラクティス

コメント

タイトルとURLをコピーしました