MSDN Ultimate Giveaway

Howdy folks,MSDN Logo

The other day, I helped out Rob Collie (@powerpivotpro) with something, and in return he provided me a MSDN Ultimate subscription. I don’t really have a need for this, however, as I have MSDN and Technet access already, so I’m giving it away to someone in the community. I can’t think of any super creative ways to choose a winner, so I’ll go with the old “pick a number” routine, somewhere between 1 and 2000. The number has some significance to me, though I wouldn’t expect anyone else to know why that is.

The main rule is that you can only submit one number per 24-hour interval, and if you post more than once in 24 hours, you will be disqualified. So go ahead … post your guesses in the comments section! Comments will be closed at 9 AM Central Time on Friday, January 28th, 2011. The person with the closest number at that time will win the subscription.

Removing Permanent WMI Event Registrations

Introduction

Since I’ve worked on the PowerEvents PowerShell module, several folks have been confused about how to remove event registrations once they’ve been created. I wrote some documentation that’s included in the download, that explains how to manually remove these registrations using the built-in wbemtest tool. This is the fool-proof method, since wbemtest is included in every Windows installation.

In the interest of making things easier, however, I wrote a WinForms utility in C# a little while back. This utility simply enumerates the various permanent event objects in the WMI repository (filters, consumers, and bindings), and allows you to remove them. That’s all it does :)

In the remainder of this blog post, I’ll talk about the manual method of removing event objects, and show you the utility I just mentioned.

The Manual Method

While experimenting with the PowerEvents module, you might accumulate many WMI event filter and consumer objects. At some point, you’ll probably want to clear those out. As of this writing, the PowerEvents module needs further work on the Get-* and Remove-* advanced functions. Until this functionality can be implemented, use the following procedure to remove the filter/consumer bindings.

Here are the individual steps to remove an unwanted event binding:

  1. Open wbemtest as an administrator
  2. Click Connect
  3. In the Namespace field, type rootsubscription
  4. Click Connect or press {ENTER}
  5. Click Enum Instances
  6. Type __FilterToConsumerBinding in the text box
  7. Click OK or press {ENTER}
  8. Click the binding instance you want to remove
  9. Click the Delete button

Upon removal of the __FilterToConsumerBinding instance, the consumer will no longer respond to events. This process can be repeated to remove filters and consumers. Rather than enumerating instances of __FilterToConsumerBinding however, you would use “__EventFilter” or any of the five consumer class names.

The WMI Event Helper Utility

The utility I wrote a little while back is intended to display all filters, consumers, and event bindings to you, so that you can remove them from a friendly GUI. Although it works quite well in my personal testing, the tool has one important limitation, albeit it probably won’t affect most people.

The Limitation

In its current form, it does not allow you to specify a WMI namespace where the event objects reside. As I said, most folks should be OK, but you should be aware that you can create WMI filter objects in ANY WMI namespace, not just rootsubscription (the default). The out-of-box consumer instances can be created in either rootdefault or rootsubscription (latter is default). Finally, event bindings can be created in ANY WMI namespace.

Unless you’re explicitly specifying an alternate WMI namespace when creating the various WMI event objects, you won’t be affected by this. Just be aware that, if you’re a power user, you might want to make sure you don’t have event objects in other namespaces.

The Tool

Here’s what the tool looks like:

image

As you can see, it lists filters, consumers, and bindings in the rootsubscription namespace. You might notice that above the consumer list, there’s a “Consumer Type” combo box. By clicking the arrow, or scrolling through the list using your mouse scroll wheel (the control must have focus), you can select the Consumer Class that you want to enumerate instances of.

Simply click on the item you want to delete, and select the appropriate “Remove” button. That’s all there is to it!

You can download the WMI Event Helper utility on the PowerEvents project page.

Conclusion

This blog post has covered the removal of WMI permanent event objects both manually, and using a C# event management utility. For more information, please review the comprehensive documentation included in the PowerEvents module release download.

PowerShell: WMI Eventing: Monitor CPU Speed

Introduction

I haven’t written any articles in a while, and the last major stuff I had been working with involved permanent WMI event subscriptions. I’ve been itching to write an article like this for a while now, but just had never gotten around to it. The purpose of this article is to describe how to use PowerShell with WMI eventing to monitor changes in CPU speed. Unlike early generation CPUs, modern CPUs have embedded technology that can dynamically change the processor’s clock speed dependent on load (eg. Intel SpeedStep or AMD’s Cool ‘n Quiet).

WMI Events

Thankfully, the Windows Management Instrumentation (WMI) service, built into Microsoft Windows, offers information about CPU speed, as well as For some background on temporary WMI event subscriptions with PowerShell, check out my article on WMI events. If you’re interested in permanent event subscriptions, that don’t depend on PowerShell running in the background, check out the PowerShell PowerEvents module.

Temporary: Monitoring CPU Speed

Using a temporary event subscription, we can easily monitor CPU speed by running the following PowerShell command:

Register-WmiEvent –Query "select * from __InstanceModificationEvent within 2 where TargetInstance ISA 'Win32_Processor' and TargetInstance.CurrentClockSpeed <> PreviousInstance.CurrentClockSpeed" –Action { Write-Host "Clock speed changed" }

This will simply echo the text “Clock speed changed,” at each occurrence, to the PowerShell console. If you want to do something more fancy, you can dynamically retrieve the new clock speed from the event object in the Action block.

Register-WmiEvent –Query "select * from __InstanceModificationEvent within 2 where TargetInstance ISA 'Win32_Processor' and TargetInstance.CurrentClockSpeed <> PreviousInstance.CurrentClockSpeed" –Action { Write-Host ("Clock speed changed to: " + $Event.SourceEventArgs.NewEvent.TargetInstance.CurrentClockSpeed + "Mhz") }

image

To make things even more dynamic, we can set up a PowerShell function to respond to our event, and then call that function in the event handler. By doing this, we now allow ourselves the flexibility of redefining the event handler function, without having to delete and re-create the event registration.

function ClockSpeedChanged($tEvent)
{
    Write-Host $tEvent.SourceEventArgs.NewEvent.TargetInstance.CurrentClockSpeed
}

Register-WmiEvent –Query "select * from __InstanceModificationEvent within 2 where TargetInstance ISA 'Win32_Processor' and TargetInstance.CurrentClockSpeed <> PreviousInstance.CurrentClockSpeed" –Action { ClockSpeedChanged $Event }

Permanent: Monitoring CPU Speed

So, now we’ve looked at how to create a temporary event registration to monitor CPU speed, but this depends on having PowerShell.exe running all the time. What if we wanted to perform some action in response to the CPU speed changing, but not have to worry about invoking, and leaving, a PowerShell session? This is where the power of WMI permanent event subscriptions comes into play. The PowerEvents module for PowerShell makes these quite easy to work with.

To recap on permanent event consumers, you need to create three objects:

  1. A filter that defines the events you’re catching / responding to
  2. A consumer which defines the action that will be taken in response to event instances
  3. A binding which binds a filter to a consumer, and enables the flow of events

First, we need to create a filter object. Filters in WMI are simply objects that define which events you want to capture and respond to. The actually action of responding is handled by a different object, called a consumer. Here’s what our filter would look like:

$Filter = New-WmiEventFilter –Name CPUClockSpeedChanged –Query "select * from __InstanceModificationEvent within 2 where TargetInstance ISA 'Win32_Processor' and TargetInstance.CurrentClockSpeed <> PreviousInstance.CurrentClockSpeed"

Next, we need to create a WMI event consumer. The consumer’s purpose is to respond to the events defined in our filter. Let’s say in this case, that we want to simply log the clock speed change to a text file:

$Consumer = New-WmiEventConsumer -Name CPUClockSpeedChanged -ConsumerType LogFile -FileName c:tempClockSpeed.log -Text "Clock speed on %TargetInstance.SocketDesignation% changed to: %TargetInstance.CurrentClockSpeed%" 

Note: For the above example, make sure that the folder c:temp exists, otherwise it will not be created. The consumer will only create the text file, if it does not exist.

Finally, we create a binding between the filter and the consumer:

New-WmiFilterToConsumerBinding -Filter $Filter -Consumer $Consumer

And that’s all there is to it! Now you should start seeing events get logged to c:tempClockSpeed.log when your processor’s speed changes. If you’re on a laptop, try unplugging your AC adapter to invoke a speed change. If you’re on a desktop computer, try putting it under load by starting a bunch of programs, and then letting it settle. Assuming that you’ve not disabled power saving features in your BIOS, you should see the clock speeds changing, and getting logged.

image