Friday, October 07, 2011

Using PowerShell with WMI Events

I’ve been working on a WMI and PowerShell video course for PluralSight (due out soon) and am today working on the last bit of the course which covers Events. I found an MSDN sample written in VBScript. Here’s the VBScript:

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    WScript.Echo (objObject.TargetInstance.Message)
End Sub

Set objWMIServices = GetObject( _
    "WinMgmts:{impersonationLevel=impersonate, (security)}") 

Set sink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
objWMIServices.ExecNotificationQueryAsync sink, _
    "SELECT * FROM __InstanceCreationEvent " & _
    "WHERE TargetInstance ISA 'Win32_NTLogEvent' "
I spent some time looking at this trying to get my head around what it was actually doing.   Turns out that translating it into PowerShell was fairly simple. Here’s the PowerShell code:

$query = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent' "

Register-WmiEvent -Source Demo1 -Query $query -Action {
                Write-Host "Log Event occurred"
                Write-Host "EVENT MESSAGE"
                Write-Host $event.SourceEventArgs.NewEvent.TargetInstance.Message}

Even with the nice spacing that turns 9 hard to understand lines of VB SCript into 2 LONG lines of PowerShell (or 5 as it’s so nicely spaced out here). I could have written it as a one-liner had I wished to go for compactness – but I think spacing it out a bit helps in terms of understaning.

The bottom line for me is that PowerShell is just so much easier to understand – you register for an event. A query tells you which event. And when that event fires, you take some action. Job done.

Technorati Tags: ,

1 comment:

Jeffery Hicks said...

You can also create an event subscriber for things that happen on remote computers. When I do that I like to create a query with a polling interval and that is very specific. If you don't specify an action scriptblock, then the event is written to the event queue which you can see with Get-Event.

Unlike VBScript where you needed to keep the script running in order to receive events, here all you need is to keep your PowerShell session open.