本番で動かすスクリプトには必ずエラーハンドリングが必要です。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関数を作ってすべてのスクリプトで使い回すのがベストプラクティス



コメント