Windows 10 Anniversary UpdateからサポートしたWindows Subsystem for Linux(WSL)。その結果としてWindows 10上でもBashを始めとするLinuxコマンドが利用可能になった。本連載ではWSLに関する情報や、Bashから実行するシェルスクリプトを紹介する。今回は、Windows 10のイベントログをCutで切り出し、簡単な可視化を行ってみよう。
WSLとウイルス対策ソフトなどの互換性が向上
2016年11月3日(現地時間)にリリースされたWindows 10 Insider Preview ビルド14959は、リリースノートによると、最新のWSL(Windows Subsystem for Linux)はPicoプロセス通知の改善や、EDP(Enterprise Data Protection)有効時にBUW(Bash on Ubuntu on Windows)を起動すると0x80070057エラーが発生する問題、Windows 10との相互運用性や安定性の向上、各種バグフィックスが加わっている。
今回のOSビルドで興味深いのが、公式ブログに投稿された「WSL Antivirus and Firewall Compatibility」だ。こちらの記事によれば、Windows 10 Anniversary Update(バージョン1607)から搭載されたWSLベータ版は、サードパーティ製ウイルス対策ソフトとの競合により、いくつかの機能が動作しないケースがあるという。MicrosoftのJack Hammons氏は、「インターネットへアクセスするユーザーを阻止し、WSLのインストールや特定のディレクトリ(フォルダー)アクセスを防止。そして、BUW使用時にファイルパーミッションが原因で発生する予期せぬ行動」があるという。
これらの問題を改善するため、WSL開発陣は「プロセスおよびスレッドのサブシステムタイプを照会する機能」「サブシステムによるPSスレッドおよびプロセス通知の拡張」を次のビルドから追加することを明らかにした。ウイルス対策ソフトやファイアウォールソリューションを開発するソフトウェアベンダーは、新たに用意したAPIを用いることで、脅威の検出ロジックを維持したままWSLとの衝突を回避可能になるという。2017年3月リリース予定の次期大型アップデート「Windows 10 Creators Update」は、ベンダーの対応が追いつかない場合、一部ソフトウェアの動作に影響を与えそうだ。
イベントログを可視化する
さて、Windows 10では多くのログファイルをETW(Event Tracing for Windows)化し、テキスト形式ではなくなっている。例えばWindows Updateの実行ログだった「%SystemRoot%\System32\WindowsUpdate.log」ファイルは存在するものの、その内容は下図に示したとおり、ETW化の説明とPowerShellによる変換方法が記述されているのみだ。
この説明にあるとおり、管理者権限を持つPowerShell上で「Get-WindowsUpdateLog」を実行すると、Windows Performance Analyzer Traceファイル形式で保存されているログ情報を読み込み、インターネット経由で変換に必要なデバッグ用のシンボル情報をダウンロードして、「WindowsUpdate.log」ファイルに変換するため、数分程度の時間を要する。本来であれば初回はシンボルファイルの展開をうながすダイアログが出るはずだが、筆者の環境では正しく動作しない。こちらのサイトから、Windows 10のバージョンと合致するWindows Symbol Packagesをダウンロードし、Windows SDKに含まれるTraceFmt.exeを使った変換も試してみたが結果は同じだった。
そこで今回は「イベントビューアー」に登録されたイベントログをCSVファイルに出力して、イベントログの状態を可視化するシェルスクリプトにチャレンジしてみよう。イベントログの出力方法はPowerShellなど各種方法があるものの、今回は初回ということもあって、GUIからメニューを使ってCSVファイルを出力させた。
下図に示したのが、CSVファイルの内容だ。ご覧のとおり「レベル」「日付と時刻」「ソース」「イベントID」「タスクのカテゴリ」といった項目が並ぶ。ただし、より詳細な内容に関しては正しいCSV形式ではなく、改行を含んだ文字列が加わっているため、そのままでは使用できない。そこで、先頭行となるレベルが「重大」「警告」「詳細」「エラー」「情報」であるか否かで区別ことにする。
後はレベルの文字列を取得し、カウントしていけばよい。それを実行するのが以下のシェルスクリプトだ。いつもと同じくお使いの環境に合わせて変数の値を変更し、シェルスクリプトに実行権限を与えてからお試し頂きたい。
#!/bin/bash
BASEFILE=/mnt/c/Users/kaz/Desktop/System.csv
Count_Critical=0
Count_Alert=0
Count_Details=0
Count_Error=0
Count_Info=0
for Line in `cat $BASEFILE`; do
X=`echo ${Line} | cut -d "," -f 1`
case $X in
"重大" )
Count_Critical=$((Count_Critical+1)) ;;
"警告" )
Count_Alert=$((Count_Alert+1)) ;;
"詳細" )
Count_Details=$((Count_Details+1)) ;;
"エラー" )
Count_Error=$((Count_Error+1)) ;;
"情報" )
Count_Info=$((Count_Info+1)) ;;
esac
done
echo 重大レベルは $Count_Critical 件
echo 警告レベルは $Count_Alert 件
echo 詳細レベルは $Count_Details 件
echo エラーレベル $Count_Error 件
echo 情報レベルは $Count_Info 件
コードをご覧になるとお分かりのとおり、行っている作業は極めてシンプルだ。10~24行のforループは、変数BASEFILEで指定したファイルを1行ずつ読み込み、11行めのechoで内容を標準出力した内容をパイプでコマンド「cut」に渡している。cutは渡された1行の内容を指定範囲して出力できるため、オプション「-d」でデリミタを「,(カンマ)」に変更。オプション「-f」で抽出対象フィールドを1つめにしている。後は12~23行のcase文で変数xの内容(レベル)に応じて、変数Count_Criticalなどをインクリメントし、forループを終えた26~30行で結果を出力する。
今回はログを可視化する骨子としてシンプルなシェルスクリプトとなったが、自動化という観点から見れば、イベントログの自動抽出や期間指定、他の要素を参照するといった拡張性もある。現場の需要に応じてカスタマイズしてほしい。
阿久津良和(Cactus)