LoginSignup
51
27

More than 5 years have passed since last update.

Powershellスクリプト 例外処理の罠

Posted at

はじめに

Powershellで大き目の規模の自動化スクリプトを開発する際のエラーハンドルではまりやすいところ

例外ハンドルについて

Powershellスクリプトで例外をcatchする場合は以下のとおり記述します。

test.ps1
try{
    #write some code
}catch{
    #write some code if error occured
}finally{
    #write some code
}

しかし、Powershellでは.NetのPowershellのコマンドレットだけでなく、net useのようなコマンドを利用することがあります。

この場合、以下のように記述してもエラーをハンドルできません。

test.ps1
try{
    net use \\hostname\share password /user:user
}catch{
    Write-Error("エラー"+$_.Exception)
}finally{
    #write some code
}

これは、netuse.exeを実行した結果を文字列で出力されるだけで、エラーを扱うには一工夫必要です。
また、ファイル操作系のコマンド実行でもエラーがcatchされないことがありました。

test.ps1
try{
    Move-Item -Path "SrcPath" -Destination "DstPath"
}catch{
    Write-Error("エラー"+$_.Exception)
}finally{
    #write some code
}

① エラー判定

環境変数「$LASTEXITCODE」を利用する

例としてnet useコマンドを例に挙げましたが、.exeファイルの実行後、Powershellの環境変数である$LASTEXITCODEに値が格納されます。

一般的には、正常終了していれば0が格納されており、以下のようにできます。

test.ps1
try{
    net use \\hostname\share password /user:user
    if($LASTEXITCODE -ne 0){
        throw
    }
}catch{
    Write-Error("エラー"+$_.Exception)
}finally{
    #write some code
}

ただ、これが使えるのは外部スクリプトの実行の場合なので、上記ファイル操作系のコマンドには利用できません。
なので、ファイル操作系は以下のオプションを利用します。

test.ps1
try{
    Move-Item -Path "SrcPath" -Destination "DstPath" -ErrorAction Stop
}catch{
    Write-Error("エラー"+$_.Exception)
}finally{
    #write some code
}

② エラー内容

エラーの内容を取得するには以下の方法があります。

1. $.Exception($.Exception.Message)

発生した直近の例外が格納されています。
catch句の中で利用します。

2. $ERROR

セッション内で発生したエラーを配列で格納しています。
net useコマンドでエラーが発生した場合もエラー内容を保持しています。

Powershell勉強中のため、マサカリどんどんお待ちしてます。

51
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
27