イベントの監視

システム管理者は、WMI を使用してネットワーク上のイベントを監視できます。 次に例を示します。

  • サービスが予期せず停止する。
  • サーバーが使用できなくなる。
  • ディスク ドライブの容量が 80% になる。
  • セキュリティ イベントが NT イベント ログに報告される。

一部の WMI プロバイダーはイベント プロバイダーであるため、WMI ではイベント検出とイベント コンシューマーへの配信がサポートされています。 詳細については、「WMI イベントの受信」を参照してください。

イベント コンシューマーは、イベントの通知を要求し、特定のイベントが発生したときにタスクを実行するアプリケーションまたはスクリプトです。 イベントがいつ発生するかを一時的に監視するイベント監視スクリプトまたはアプリケーションを作成できます。 WMI から、プレインストールされた永続イベント プロバイダーのセットと、イベントを永続的に監視できる永続コンシューマー クラスも提供されます。 詳細については、「標準コンシューマーを使用したイベントの監視と対応」を参照してください。

このトピックでは、以下のセクションについて説明します。

一時イベント コンシューマーを使用する

一時イベント コンシューマーは、イベント クエリまたはフィルターに一致するイベントを返すスクリプトまたはアプリケーションです。 一時イベント クエリでは、通常、C++ アプリケーションでは IWbemServices::ExecNotificationQuery、スクリプトおよび Visual Basic では SWbemServices.ExecNotificationQuery が使用されます。

イベント クエリは、特定の種類のイベント (Win32_ProcessTraceRegistryKeyChangeEvent など) を指定するイベント クラスのインスタンスを要求します。

以下の VBScript コード例では、Win32_ProcessTrace のインスタンスが作成されるときに通知を要求します。 このクラスのインスタンスは、プロセスが開始または停止されたときに生成されます。

スクリプトを実行するには、スクリプトを event.vbs という名前のファイルにコピーし、cscript event.vbs コマンド ラインを使用します。 Notepad.exe などのプロセスを開始して、スクリプトからの出力を確認できます。 スクリプトは、5 つのプロセスが開始または停止した後に停止します。

このスクリプトは、メソッドの "半同期" バージョンである SWbemServices.ExecNotificationQuery を呼び出します。 SWbemServices.ExecNotificationQueryAsync を呼び出して非同期の一時イベント サブスクリプションを設定する例については、次のスクリプトを参照してください。 詳細については、メソッドの呼び出しに関するページを参照してください。 このスクリプトで、イベントが届くたびに取得および処理されるように SWbemEventSource.NextEvent を呼び出します。 .vbs 拡張子を持つファイルにスクリプトを保存し、CScript: cscript file.vbs を使用してコマンド ラインでスクリプトを実行します。

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" _
    & strComputer & "\root\CIMV2") 
Set objEvents = objWMIService.ExecNotificationQuery _
    ("SELECT * FROM Win32_ProcessTrace")

Wscript.Echo "Waiting for events ..."
i = 0
Do Until i=5
    Set objReceivedEvent = objEvents.NextEvent
    'report an event
    Wscript.Echo "Win32_ProcessTrace event occurred" & VBNewLine _
        & "Process Name = " _
            & objReceivedEvent.ProcessName & VBNewLine _
        & "Process ID = " _
            & objReceivedEvent.Processid & VBNewLine _
        & "Session ID = " & objReceivedEvent.SessionID 
i = i+ 1
Loop

一時イベント コンシューマーは手動で開始する必要があり、WMI の再起動やオペレーティング システムの再起動をまたいで持続することはできません。 一時イベント コンシューマーは、実行中にのみイベントを処理できます。

次の手順で、一時イベント コンシューマーを作成する方法について説明します。

一時イベント コンシューマーを作成するには、次のようにします

  1. 使用するプログラミング言語を決定します。

    プログラミング言語によって、使用する API が決まります。

  2. WMI アプリケーションを起動するのと同じ方法で、一時イベント コンシューマー アプリケーションのコーディングを開始します。

    コーディングの最初のステップは、プログラミング言語によって異なります。 通常は、WMI にログオンし、セキュリティ設定を設定します。 詳細については、「WMI アプリケーションまたはスクリプトの作成」を参照してください。

  3. 使用するイベント クエリを定義します。

    一部の種類のパフォーマンス データを取得するには、高パフォーマンス プロバイダーから提供されるクラスの使用が必要になる場合があります。 詳細については、「パフォーマンス データの監視」、「受信するイベントの種類の決定」、「WQL を使用したクエリ」を参照してください。

  4. 非同期呼び出しまたは半同期呼び出しのいずれかを行うことを決定し、API メソッドを選択します。

    非同期呼び出しを行うと、データのポーリングのオーバーヘッドを回避できます。 一方、半同期呼び出しを行うと、同様のパフォーマンスが得られ、セキュリティが強化されます。 詳細については、メソッドの呼び出しに関するページを参照してください。

  5. 非同期メソッドまたは半同期メソッドを呼び出し、strQuery パラメーターとしてイベント クエリを含めます。

    C++ アプリケーションの場合は、次のメソッドを呼び出します。

    スクリプトの場合は、次のメソッドを呼び出します。

  6. 返されるイベント オブジェクトを処理するコードを記述します。

    非同期イベント クエリの場合は、オブジェクト シンクのさまざまなメソッドまたはイベント内にコードを記述します。 半同期イベント クエリの場合は、WMI が取得するたびにオブジェクトが返されるため、各オブジェクトを処理するループ内にコードを記述する必要があります。

次のスクリプト コード例は、Win32_ProcessTrace スクリプトの非同期バージョンです。 非同期操作では直ちに返されるため、ダイアログ ボックスはイベントの待機中にスクリプトをアクティブな状態に保ちます。

各イベントを受信するために SWbemEventSource.NextEvent を呼び出す代わりに、このスクリプトには、SWbemSink OnObjectReady イベントのためのイベント ハンドラーがあります。

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & _
    strComputer & "\root\CIMV2") 
Set EventSink = WScript.CreateObject( _
    "WbemScripting.SWbemSink","SINK_")

objWMIservice.ExecNotificationQueryAsync EventSink, _
    "SELECT * FROM Win32_ProcessTrace WITHIN 10"
WScript.Echo "Waiting for events..."

i = 0
While (True)
    Wscript.Sleep(1000)
Wend

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    Wscript.Echo "Win32_ProcessTrace event has occurred."
    i = i+1
    If i = 3 Then WScript.Quit 0 
End Sub

注意

SINK_OnObjectReady サブルーチンによって処理されるコールバックなどの非同期コールバックを使用すると、認証されていないユーザーがシンクにデータを提供できます。 セキュリティを高めるには、半同期通信または同期通信のいずれかを使用します。 詳細については、次のトピックを参照してください。

 

永続イベント コンシューマーを使用する

永続イベント コンシューマーは、登録が明示的に取り消されるまで実行され、WMI またはシステムの再起動時に起動します。

永続イベント コンシューマーは、システム上の WMI クラス、フィルター、および COM オブジェクトの組み合わせです。

以下に、永続イベント コンシューマーの作成に必要なパーツを列挙します。

  • 永続コンシューマーを実装するコードを含む COM オブジェクト。
  • 新しい永続コンシューマー クラス。
  • 永続コンシューマー クラスのインスタンス。
  • イベントのクエリを含むフィルター。
  • コンシューマーとフィルターの間のリンク。

詳細については、イベントの常時受信に関するページを参照してください。

WMI から、永続コンシューマーがいくつか提供されます。 コンシューマー クラスとコードを含む COM オブジェクトがプレインストールされています。 たとえば、イベントが発生したときにスクリプトを実行するように ActiveScriptEventConsumer クラスのインスタンスを作成および構成できます。 詳細については、「標準コンシューマーを使用したイベントの監視と対応」を参照してください。 ActiveScriptEventConsumer の使用例については、「イベントに基づくスクリプトの実行」を参照してください。

次の手順で、永続イベント コンシューマー クラスを作成する方法について説明します。

永続イベント コンシューマー クラスを作成するには、次のようにします

  1. 使用している名前空間にイベント プロバイダーを登録します

    一部のイベント プロバイダーでは、特定の名前空間のみを使用できます。 たとえば、__InstanceCreationEventWin32 プロバイダー によってサポートされている組み込みイベントで、既定では \root\cimv2 名前空間に登録されます。

    注意

    登録で使用される __EventFilterEventNamespace プロパティを使用して、名前空間に共通のサブスクリプションを作成できます。 詳細については、「名前空間に共通の永続イベント サブスクリプションの実装」を参照してください。

     

  2. イベント クラスが配置されている名前空間にイベント コンシューマー プロバイダーを登録します

    WMI では、永続的なイベント コンシューマーを検索するためにイベント コンシューマー プロバイダーが使用されます。 永続イベント コンシューマーは、イベントの受信時に WMI によって起動されるアプリケーションです。 イベント コンシューマーを登録するには、プロバイダーによって __EventConsumerProviderRegistration のインスタンスが作成されます。

  3. 使用する永続イベント コンシューマーを表すクラスのインスタンスを作成します。

    イベント コンシューマー クラスは、クラス __EventConsumer から派生します。 イベント コンシューマー インスタンスに必要なプロパティを設定します。

  4. regsvr32 ユーティリティを使用して、COM にコンシューマーを登録します。

  5. イベント フィルター クラス __EventFilter のインスタンスを作成します。

    イベント フィルター インスタンスの必須フィールドを設定します。 __EventFilter の必須フィールドは、NameQueryLanguageQuery です。 Name プロパティには、このクラスのインスタンスに対して任意の一意の名前を指定できます。 QueryLanguage プロパティは常に "WQL" に設定されます。 Query プロパティは、イベント クエリを含む文字列です。 永続イベント コンシューマーのクエリが失敗すると、イベントが生成されます。 このイベントのソースは WinMgmt、イベント ID は 10、イベントの種類は Error です。

  6. __FilterToConsumerBinding クラスのインスタンスを作成して、論理イベント コンシューマーをイベント フィルターに関連付けます。

    WMI によって関連付けが使用され、イベント フィルターに指定した条件に一致するイベントに関連付けられているイベント コンシューマーが検索されます。 WMI によってイベント コンシューマー プロバイダーが使用され、起動する永続イベント コンシューマー アプリケーションが検索されます。