第1回 フォルダー内のJPEGファイルを連番でリネームする 第2回 他の画像形式をJPEG形式に変更する 第3回 ピクセルサイズに応じて画像ファイルをリサイズする 第4回 実行先のフォルダーを引数で指定する 第5回 case文でスクリプト内容を整理する
第6回Webページの情報をシェルスクリプトで取得する 第7回取得結果をCSVファイルやテキストファイルに出力する 第8回インターネットショートカットファイルを作成する 第9回散らかったデスクトップを片付ける 第10回時間軸でデスクトップを片付ける
第11回BashからExcelブックにアクセスする 第12回フォルダーの中のエクセル請求書ファイルを合計する 第13回フォルダの中のファイルを一括でPDFにするには 第14回整理整頓!空のフォルダを一括でデスクトップに移送する 第15回ファイル名ではなく内容判断で重複ファイルを削除するには?
第16回文章をMarkdown記法で整える 第17回複数PDFファイルから一括テキスト抽出 第18回PDFファイルから一括で大量の画像を抽出 第19回 PDFファイルを画像ファイル化する

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による変換方法が記述されているのみだ。

「%SystemRoot%\System32\WindowsUpdate.log」の内容。こちらが更新されることはない

ログの実体は「%SystemRoot%\Logs\WindowsUpdate」フォルダーに格納されている

この説明にあるとおり、管理者権限を持つPowerShell上で「Get-WindowsUpdateLog」を実行すると、Windows Performance Analyzer Traceファイル形式で保存されているログ情報を読み込み、インターネット経由で変換に必要なデバッグ用のシンボル情報をダウンロードして、「WindowsUpdate.log」ファイルに変換するため、数分程度の時間を要する。本来であれば初回はシンボルファイルの展開をうながすダイアログが出るはずだが、筆者の環境では正しく動作しない。こちらのサイトから、Windows 10のバージョンと合致するWindows Symbol Packagesをダウンロードし、Windows SDKに含まれるTraceFmt.exeを使った変換も試してみたが結果は同じだった。

そこで今回は「イベントビューアー」に登録されたイベントログをCSVファイルに出力して、イベントログの状態を可視化するシェルスクリプトにチャレンジしてみよう。イベントログの出力方法はPowerShellなど各種方法があるものの、今回は初回ということもあって、GUIからメニューを使ってCSVファイルを出力させた。

「eventvwr.exe」を実行するなどして「イベントビューアー」を起動し、対象とするログのカテゴリーを右クリック。<すべてのイベントを名前をつけて保存>をクリックする

任意のファイル名をテキストボックスに入力し、<保存>ボタンをクリックする

下図に示したのが、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行で結果を出力する。

シェルスクリプトを実行すると、forループとcase文で振り分けた結果が示される

今回はログを可視化する骨子としてシンプルなシェルスクリプトとなったが、自動化という観点から見れば、イベントログの自動抽出や期間指定、他の要素を参照するといった拡張性もある。現場の需要に応じてカスタマイズしてほしい。

阿久津良和(Cactus)