[PowerShell実践] 第5回 WMI 関連の Cmdlet (Register-WmiObject)


スポンサーリンク


この章の目次と概要です。

 
今回は、Register-WmiObject について記述していますが、他の Cmdlet について記述していますので、気になる Cmdlet がありましたら参照ください。

表. WMI関連のコマンドレット(Cmdlet)
Cmdlet 機能
Get-WmiObject WMI クラスのインスタンスまたは使用可能なクラスに関する情報を取得する。
Invoke-WmiMethod WMI メソッドを呼び出す。
Register-WmiEvent WMI イベントをサブスクライブする。
Remove-WmiObject 既存の WMI クラスのインスタンスを削除する。
Set-WmiInstance 既存の WMI クラスのインスタンスを作成または更新する。

Register-WmiObject の使い方

Register-WmiObject を使用すると、プロセスの起動や停止、イベントログの追加といったイベント発生時に特定の処理を実行させることができます。

Register-WmiObject の実行時に引数として -Action { イベント発生時の処理を記述 } を指定すれば、イベント発生時の処理を記述することができます。
-Action を指定しなかった場合は、イベント発生を取得するために、Wait-Event を使用します。

Register-WmiObject を実行すると、イベント サブスクライバーが登録されますが、登録されたイベント サブスクライバーを確認するには Get-EventSubscriber を使用します。

Register-WmiObject で登録したイベント サブスクライバーは、現在のセッションでのみ有効です。そのため、PowerShell 終了時にはイベント キューが破棄され、イベント サブスクライバーは削除されます。

セッションを終了する前など、明示的に登録したイベント サブスクライバーを削除するには Unregister-Event を使用します。

以下にコマンドを整理します。

表. Register-WmiObject 関連コマンドの主な使い方
処理 使用例
イベント サブスクライバー
の登録
> Register-WMIEvent -query “WQL クエリを記述
  -sourceIdentifier “名前
  -Action { イベント発生時の処理を記述 }
または
> Register-WMIEvent -query “WQL クエリを記述
  -sourceIdentifier “名前
イベント取得 > $Event = Wait-Event -SourceIdentifier “名前
※ Register-WmiEvent で -Action を指定しなかった場合
現在のセッションの
イベント サブスクライバーの取得
> Get-EventSubscriber
イベント サブスクライバー
の削除
> Unregister-Event 名前
または
> Unregister-Event ID

 

Register-WmiObject でイベントログを監視

それでは実際に、”アプリケーションのイベントログで、イベントID 999 が発生したら、ファイルにイベント内容を書き込む” ということをやってみます。

実際に実行した内容は以下の通りです。

C:\>powershell
Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. All rights reserved.

PS C:\> Unregister-Event AppEventlog_EventID999
PS C:\> Register-WMIEvent -query "Select * From __InstanceCreationEvent within 3 `
>> Where TargetInstance ISA 'Win32_NTLogEvent' `
>> AND TargetInstance.LogFile = 'Application' AND TargetInstance.EventCode = '999'" `
>> -sourceIdentifier "AppEventlog_EventID999" `
>> -Action { $Event.SourceEventArgs.NewEvent.TargetInstance | Out-File -FilePath "c:\test\AppEventlog_EventID999.txt" -Append}
>>                                                     ・・・(1)

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
1      AppEventlog_...                 NotStarted    False                                 $Event.SourceEventArg...


PS C:\> type C:\test\AppEventlog_EventID999.txt        ・・・(2)
type : パス 'C:\test\AppEventlog_EventID999.txt' が存在しないため検出できません。
発生場所 行:1 文字:1
+ type C:\test\AppEventlog_EventID999.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\test\AppEventlog_EventID999.txt:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

PS C:\> eventcreate /T INFORMATION /L APPLICATION /ID 999 /D "Test Message"
    ・・・(3)

成功: 種類が 'INFORMATION' のイベントが、'APPLICATION' ログ内に、'EventCreate' をソースとして作成されました。
PS C:\> type C:\test\AppEventlog_EventID999.txt   ・・・(4)


__GENUS          : 2
__CLASS          : Win32_NTLogEvent
__SUPERCLASS     :
__DYNASTY        : Win32_NTLogEvent
__RELPATH        : Win32_NTLogEvent.Logfile="Application",RecordNumber=78718
__PROPERTY_COUNT : 16
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
Category         : 0
CategoryString   :
ComputerName     : WIN2012R2_SRV
Data             :
EventCode        : 999
EventIdentifier  : 999
EventType        : 3
InsertionStrings : {Test Message}
Logfile          : Application
Message          : Test Message
RecordNumber     : 78718
SourceName       : EventCreate
TimeGenerated    : 20140704001134.000000-000
TimeWritten      : 20140704001134.000000-000
Type             : 情報
User             : WIN2012R2_SRV\Administrator
PSComputerName   :



PS C:\> Get-Eventsubscriber                       ・・・(5)


SubscriptionId   : 2
SourceObject     : System.Management.ManagementEventWatcher
EventName        : EventArrived
SourceIdentifier : AppEventlog_EventID999
Action           : System.Management.Automation.PSEventJob
HandlerDelegate  :
SupportEvent     : False
ForwardEvent     : False



PS C:\> Unregister-Event AppEventlog_EventID999   ・・・(6)
PS C:\> Get-Eventsubscriber                       ・・・(7)
PS C:\>

各行の説明
(1) イベント サブスクライバーを登録。
    アプリケーションのイベントログで、イベントID 999 が発生したら、
    C:\test\AppEventlog_EventID999.txt にイベントログを書き込む。
(2) C:\test\AppEventlog_EventID999.txt が、まだ存在しないことを確認。
(3) 対象のイベントログを発生。
(4) C:\test\AppEventlog_EventID999.txt に書き込まれていることを確認。
(5) 登録済みのイベント サブスクライバーを表示。
(6) 名前を指定してイベント サブスクライバーを削除。
    この場合、SubscriptionId が 2 なので、”Unregister-Event 2″ でもよい。
(7) イベント サブスクライバーが削除されたことを確認。

 

ほとんど同じ内容ですが、
Register-WmiEvent 時に -Action を指定しない場合 (Wait-Event を使用する場合) のスクリプトを作成してみます。

以下の内容を記述し、C:\unyo\powershell\test\get_WmiEventlog.ps1 として保存します。

Write-Host "終了させるには Ctrl + C を入力して下さい"

# Register-WmiEvent で指定する名前
$name = "AppEventlog_EventID999"

# イベント サブスクライバー登録
Register-WmiEvent -query "Select * From __InstanceCreationEvent `
    within 3 Where TargetInstance ISA 'Win32_NTLogEvent' `
    AND TargetInstance.LogFile = 'Application' `
    AND TargetInstance.EventCode = '999'" `
    -sourceIdentifier $name


While ($true) {
    # EventID 999 取得
    $newEvent = Wait-Event -SourceIdentifier $name
    $log = $newEvent.SourceEventArgs.NewEvent.TargetInstance
    $logname  = $log.LogFile
    $source   = $log.SourceName
    $eventid  = $log.EventCode
    $generate = $log.TimeGenerated
    $message = $log.Message

    Write-Host "$logname,$source,$eventid,$generate,$message"

    # 取得したイベントを削除 (削除しないと次のイベントが取得できない)
    Remove-Event $name
}

 
以下は実行例です。
powershell .\get_WmiEventlog.ps1 を実行開始したらイベント待ち状態になるので、別途コマンド・プロンプトを立ち上げて、eventcraete コマンドでイベントを発生させています。
最後に、get_WmiEventlog.ps1 は Ctrl + C で強制終了しています。

C:\unyo\powershell\test> powershell .\get_WmiEventlog.ps1
終了させるには Ctrl + C を入力して下さい                                ・・・(1)
Application,EventCreate,999,20140704013235.000000-000,Test Message 01   ・・・(2)
Application,EventCreate,999,20140704013236.000000-000,Test Message 02   ・・・(3)
Application,EventCreate,999,20140704013239.000000-000,Test Message 03   ・・・(4)

C:\unyo\powershell\test>

各行の説明
(1) get_WmiEventlog.ps1 実行するとイベントID 999 が発生するまで待ち状態になる。
(2) 別のコマンド・プロンプトで以下を実行時した際の出力結果。
    eventcreate /T INFORMATION /L APPLICATION /ID 999 /D “Test Message 01″
(3) 別のコマンド・プロンプトで以下を実行時した際の出力結果。
    eventcreate /T INFORMATION /L APPLICATION /ID 999 /D “Test Message 02″
(4) 別のコマンド・プロンプトで以下を実行時した際の出力結果。
    eventcreate /T INFORMATION /L APPLICATION /ID 999 /D “Test Message 03″

 

 
スポンサーリンク