Windows TIPS
[PowerShell] |
PowerShellスクリプトで発生したエラー情報をイベント・ログに記録する
|
|
■ |
イベント・ログは、ハードウェアやソフトウェア、そのほか、システム全般の問題について情報を収集するための重要な手掛かりとなる。 |
■ |
PowerShellスクリプトでエラー(例外)が発生した場合にも、その詳細情報をイベント・ログに記録しておくことで、システム全体の一元的な監視が容易になる。 |
|
|
イベント・ログは、オペレーション・システム上で発生した処理全般(エラーや警告、一般的な情報など)が記録された情報である。アプリケーション上でなにかしらの障害が発生した場合にも、イベント・ログの内容を参照することで、問題発生までの過程をある程度は推察することができる。イベント・ログを参照するためのGUIツールとして「イベント・ビューア」が存在するが、読者も、なにかとこのツールを利用する機会は多いのではないか。
さて、このWindows TIPSでは多くのPowerShellスクリプトを紹介してきたが、当然、指定された引数や環境などによっては、スクリプトが予期せぬ例外(エラー)を発生することは避けられない。もちろん、例外が発生したところで、その詳細情報をエンド・ユーザが適切に記録していてくれれば、後からシステム管理者が問題を特定するのは比較的容易だろう。しかし、コンピュータ・リテラシーにばらつきのあるエンド・ユーザーに、常に適切な記録を求めるのは難しい。また、タスク・スケジューラなどで自動実行しているスクリプトで例外が発生した場合などでは、そもそもエンド・ユーザーが例外が発生していること自体に気付いていない可能性もあるだろう。
そこで本稿では、スクリプト上で例外が発生した場合に、その詳細情報をイベント・ログに記録する方法を紹介する。もちろん、独自のテキスト・ファイルなどに例外情報を記録しても構わないが、イベント・ログに情報を集約しておけば、システム管理者はそこですべての問題を確認できるので、問題発見の手間を軽減できる。
*注意 |
PowerShellを利用するには、あらかじめシステムにユーザー自身がインストールしておく必要があります。具体的なインストール方法については「PowerShellをインストールする」を参照してください。。 |
手順1――テキスト・エディタでPowerShellのコードを入力する
まずはテキスト・エディタ(メモ帳でも何でもよい)を開き、以下のコードを入力してほしい。なお「#」で始まる行は、コードの意味を解説するためのコメント部分なので、省略してもよい。コメントにはスクリプトの簡単な説明を入れておいた。
※ファイル:Error.ps1
param([int]$num = 0)
# 例外発生時の処理を定義
trap [Exception] {
# イベント・ログに書き込む
[Diagnostics.EventLog]::WriteEntry("PowerShell Script", $error[0].exception, "Error", 1)
break
}
# 引数$numで除算した値を表示(引数$numが0の場合は例外発生)
10 / $num
"処理が終了しました。" |
|
※ サンプル・ファイルError.ps1をダウンロードするには、ここをクリックしてください。 |
PowerShellスクリプトの実行ファイルは拡張子を「.ps1」とする必要がある。ファイル名自体は何でも構わないが、ここでは「Error.ps1」という名前で保存しておこう。
コード全体の流れについてはリスト内のコメントをご覧いただくとして、ここで注目してほしいのは、次の2点だ。
1.例外を処理するのはtrapブロックの役割
PowerShellスクリプトで例外を処理するのは、trapブロックの役割だ。Visual BasicやC#などの例外処理を知っているなら、trapブロックとはcatchブロックに相当するものであると考えると分かりやすいだろう(ちなみに、いわゆるtryブロックに相当する構文はなく、PowerShellではスクリプト全体を例外監視の対象とする)。trapブロックの一般的な構文は、以下のとおりである。
trap [補足する例外] {
...例外発生時の処理...
} |
「補足する例外」については省略することも可能だ。その場合、例外の種類にかかわらず、すべての例外がtrapブロックで処理される。trapブロックの末尾には、例外処理後の挙動を制御するためのキーワード(break/continue)を指定できるが、これについては後述する。上の例では、breakを指示している。
2.EventLog.WriteEntryメソッドでイベント・ログを書き込む
EventLogクラス(System.Diagnostics名前空間)は.NET Frameworkで提供されるクラスで、イベント・ログに対する読み書きを制御するためのものだ。ここではイベント・ログを記録するWriteEntryメソッドの構文に注目してみよう。イベント・ログを読み込む方法については、今後、別TIPSで紹介する予定である。
[Diagnostics.EventLog]::WriteEntry(
イベント・ソース名,
ログに書き込む文字列,
イベントの種類,
イベントID) |
イベントの種類には、以下のような値を指定できる(本来はEventLogEntryType列挙体として指定する必要があるが、PowerShellでは自動的にキャストされるので、単なる文字列として指定できる)。
設定値 |
概要 |
Error |
エラー |
Warning |
警告 |
Information |
情報 |
SuccessAudit |
成功した監査 |
FailureAudit |
失敗した監査 |
|
イベントの種類 |
なお、$errorはPowerShellで予約された変数で、スクリプト内で発生した例外情報が新しい順に配列として格納される。ここでは$error[0]としているので、最後に発生した例外情報を取得しているわけだ。ここでは、exceptionプロパティで例外オブジェクトを取得し、その内容をイベント・ログに記録している。
手順2――PowerShellのスクリプト・コードを実行する
Error.ps1を実行するには、PowerShellのプロンプトを開いたうえで、以下のようにコマンドを実行すればよい(*)
PS > ./Error.ps1 10 ……引数10を指定して実行
1
処理が終了しました。 ……正常終了
PS > ./Error.ps1 ……引数なしで実行
0 で除算しようとしました。 ……0による除算が発生
発生場所 C:\tmp\Error.ps1:8 文字:5 ……エラー発生
+ 10 / <<<< $num |
引数$numに10を指定した場合には問題なく処理が終了している。だが引数を省略した場合は、デフォルト値の0が指定されるので例外メッセージが表示され、イベント・ログには以下のようなログ情報が記録されることが確認できる。以下は、イベント・ビューアからログ情報を確認したものである。
|
イベント・ビューアに記録されたエラー情報 |
これはイベント・ビューアで、記録されたエラー情報を確認したところ。PowerShellからのエラーが記録されている。 |
|
|
エラーのソースはスクリプト中で指定した「PowerShell Script」になっている。 |
|
|
エラーの内容。0で除算したというエラー。 |
|
例外処理後の挙動を変更するには?
前述したように、trapブロック末尾のbreak命令は、例外処理を終えた後のスクリプトの挙動を示すものだ。先ほどのサンプルでは例外処理後にそのままスクリプト自体を停止しているが、これをcontinue命令で置き換えたらどうだろう。
PS > ./Error.ps1
0 で除算しようとしました。
発生場所 C:\tmp\Error.ps1:8 文字:5
+ 10 / <<<< $num
処理が終了しました。 |
この場合、最後の「処理が終了しました。」というメッセージが出力され、例外処理後に引き続き、後続の処理が実行されていることが確認できる。
また、break/continue命令が明示的に記述されなかった場合の挙動は、変数$ErrorActionPreferenceの設定に依存する。$ErrorActionPreferenceは例外発生時の処理方法を指定するための予約変数で、宣言する場合には、一連の処理に先立って行っておこう。具体的には、以下のような値を設定できる。
設定値 |
概要 |
continue |
例外は出力しつつ、処理も継続(デフォルト) |
silentlycontinue |
例外を出力せずに、処理を継続 |
stop |
処理を終了 |
|
$ErrorActionPreferenceの設定値 |
処理の前に、「$ErrorActionPreference = "continue"」などのようにして、$ErrorActionPreferenceに値を設定しておく。 |
Windows Server Insider フォーラム 新着記事