PowerShell Answers

Adventures in PowerShell

About the author

Author Name is someone.
E-mail me Send mail

Recent posts

Recent comments

Don't show

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Launching PowerShell Scripts in Response to WMI Events

This turns out to very straightforward, the key is to use the CommandLineEventConsumer class. It allows you to launch any program in response to a WMI event. In order to use it you only need to set two properties (although there are many more to explore)

  1. Name - a unique name for your class instance
  2. CommandLineTemplate - the command you want to run

As we want to launch a PowerShell script the command line would need to be something like

powershell.exe -command C:\temp\myscript.ps1

This would run the script myscript.ps1 and pass it any parameters that are added to the command line. Within the script you can access the parameters via the $args array.

A Working Example

Lets say that we wanted to stop people running Solitaire on their PCs - it's mean but hey, we're admins! The PowerShell cmdlet stop-process will kill a process if we supply the process ID so we'll pass that out from WMI to the script and pick it up via $args.

stop-process $args[0]

As before you need to create a filter and a consumer and join them together. So this code creates a filter that looks for instances of Solitaire starting up

$EFClass = [wmiclass]"\root\subscription:__EventFilter"
$ef = $EFClass.CreateInstance()
$ef.Name = "NewProcessFilter"
$ef.Querylanguage = "WQL"
$ef.Query = "select * from __InstanceCreationEvent within 5 where targetinstance isa 'Win32_Process' and targetinstance.name = 'Solitaire.exe'"
$ef.EventNamespace = "root\cimv2"
$ef.put()

Next we create a consumer, using the CommandLineEventConsumer class. %TargetInstance.Handle% picks up the process ID from the win32_process object that triggered the event and adds it onto the end of the PowerShell command line.

$CLECClass = [wmiclass]"\root\subscription:CommandLineEventConsumer"
$clec = $CLECClass.CreateInstance()
$clec.Name = "RunPowerShell"
$clec.CommandLineTemplate = "powershell.exe -command C:\temp\myscript.ps1 %TargetInstance.Handle%"
$clec.put()

and finally join them together with an instance of the __FilterToConsumerBinding class

$FCBClass = [wmiclass]"\root\subscription:__FilterToConsumerBinding"
$fcb = $FCBClass.createinstance()
$fcb.Consumer = $clec.__Path
$fcb.Filter = $ef.__Path
$fcb.put()

Now every time you start Solitaire the PowerShell script myscript.ps1 will run and Solitaire will be terminated :-)

Note

You might get the same errors that I noted in an earlier post when you invoke the put method. This is a known bug in PowerShell 1.0 and will be fixed in v2.0. The workaround for now is to keep invoking put until it works.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: events | PowerShell | WMI
Posted by tb on Monday, January 07, 2008 3:41 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Related posts

Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

Saturday, July 05, 2008 4:41 AM