Windows PowerShell: WMI イベントに応答する

システム レベルのイベントの追跡、通知、および応答は、Windows で適切に実行されますが、Windows PowerShell を使用して実行することもできます。

Don Jones

Windows OS のすばらしい機能の 1 つは、イベントのサポートです。OS で何か処理が行われるたびに、イベントが生成されます。アプリケーションなど、コードを使用するものであれば、特定のイベントが発生したときに、適切な処理を行えるように、イベントの発生の通知を受け取るように登録できます。たとえば、ダイアログ ボックスのボタンをクリックすると、アプリケーションは "クリック" イベントの通知を受け取り、そのボタンがクリックされたときに実行すべき処理を実行する必要があることを把握します。

Windows Management Instrumentation (WMI) でもイベントを生成することが可能で、そのイベントを受け取るように Windows PowerShell v2 を登録できます。イベントが発生した際には、シェルを使用して、イベントに応じて、必要なコマンドを実行できます。通常、WMI では、非常に数が少ないイベントの中から 1 つのイベントを発生させますが、多岐に及ぶさまざまな WMI クラスに対して、同様に 1 つのイベントを発生させることができます。

WMI イベントを使用する際には、次の 3 つの重要なポイントがあります。

  • 必要なイベントを把握する
  • イベントが必要なクラスを把握する
  • Register-WMIEvent コマンドレットを使用して、イベントの通知を登録する

単純なイベント

一部の WMI クラスでは、イベントを生成します。たとえば、Win32_ProcessStartTrace クラスは、プロセスが開始されるたびにイベントを生成します。また、他の状況でもイベントを生成します。新しいプロセスのイベントが発生すると、"Process Started" というソース識別子が渡されます。イベントを登録するには、次のコマンドを実行します。

Register-WmiEvent –class "Win32_ProcessStartTrace" 
–sourceIdentifier "Process Started"

もちろん、プロセスが開始されたことを把握するだけでは役に立ちません。プロセスが開始されたことをログに記録する、電子メールで通知する、プロセスを終了するなど、なんらかの操作を定義する必要があります。

Get-EventSubscriber コマンドレットを実行すると、作成したイベント通知のサブスクリプションを確認できます。イベントの登録をすべて削除するには、Get-EventSubscriber | Unregister-Event というコマンドを実行します。また、Unregister-Event コマンドレットを使用し、ID 番号を指定して、特定のサブスクリプションを削除することもできます。

さらに優れたイベント

WMI で生成できるシステム レベルのイベントには、さらに役に立つものがあります。たとえば、__instancecreationevent という名前のイベントは、WMI クラスの新しいインスタンスが作成されるときに必ず発生します。また、__instancedeletionevent イベントは、インスタンスが削除されるときに必ず発生します。このイベントは便利には見えないかもしれませんが、考えてみると、OS やコンピューター ハードウェアのほとんどすべての要素は、WMI クラスのインスタンスによって表されます。たとえば、Win32_LogicalDisk クラスでは、リムーバブル記憶装置を接続すると、新しいインスタンスを取得します。プロセスが終了すると、Win32_Process クラスではインスタンスを削除します。

ユーザーが新しい USB ドライブを挿入したときにメッセージが表示されるようにするには、次のコマンドを実行します。

Register-wmievent –query "select * from __instancecreationevent within 5 where targetinstance isa 'win32_logicaldisk'" –action { Write "You had better not put any proprietary information on that!" }

このクエリを分析するのは非常に困難であるため、処理内容を説明しましょう。

  • select * from __instancecreationevent (イベント名にはアンダースコアが 2 つ含まれています): 単純に、イベントのプロパティをすべて取得する必要があることを指定しています。
  • within 5: 5 秒ごとにイベントを確認するだけでよいことを示します。ここでは、あまり低い値を設定しないようにします。低い値を設定すると、更新情報を定期的に確認するために、多くのコンピューター処理能力を使用することになります。
  • where target instance isa 'win32_logicaldisk': WMI に、win32_logicaldisk クラスの新しいインスタンスを作成したイベントのみが必要であることを指定しています。

最後に、–action パラメーターでは、イベントが発生したときに、実行する必要がある操作を含むスクリプト ブロック ({ } で囲まれています) を指定しています。

–computerName パラメーターを使用して、リモート コンピューターで発生するイベントを登録するのは、便利な手法です。リモート コンピューターのローカル管理者の権限が必要ですが、操作はリモート コンピューターではなく、ローカル コンピューターで実行されます。

余談ですが、ディスク上のファイルを表す CIM_DataFile クラスに、インスタンス作成イベントを登録しないでください。WMI で新しいファイルの作成を監視するのは、あまり有効ではありません。イベントを見落とす可能性がありますし、すべてのイベントをキャッチしようとすると、非常に大きなオーバーヘッドが発生します。

注意事項とテクニック

もちろん、イベントに対する応答は、シェルが実行されている限り、継続して行われます。シェルを終了するか、なんらかの理由でシェルが自動的に終了場合、イベントの登録は解除されます。

すべてのユーザーのコンピューターで、常にシェルを起動しておくことができる可能性は、きわめて低いため、WMI イベントは、ユーザーのコンピューターで実行するには少し不便です。ただし、ユーザーがより確実に制御できるサーバーのプロセスや他の要素を監視する際、WMI イベントは非常に便利なテクニックです。

–action スクリプト ブロックでは、イベントから渡される引数を格納する、$args という名前の自動変数にアクセスできます。–action スクリプト ブロックで、Write $args というコマンドを使用して、特定の WMI イベントに存在する引数を確認できます。

WMI イベントと関連するシェル コマンドの詳細については、WMI イベント監視についての TechNet ページ (英語) を参照してください。

Don Jones

Don Jones は、Concentrated Technology の創設者で、ConcentratedTech.com (英語) で Windows PowerShell や他のテクノロジに関する質問に答えています。また、Nexus.Realtimepublishers.com (英語) の創設者でもあり、この Web サイトでは、彼の多くの著書が無料でオンライン ブックとして提供されています。

関連コンテンツ