
close
close
Chance to win $250 in Petri 2023 Audience Survey
Over the course of several articles I’ve been exploring different ways to take advantage of a PowerShell tool I built to report on remaining battery life. In a previous article, I showed you a simple script that used the Wscript.Shell COM object to display a pop-up message if the remaining battery life was at or below a given threshold. It works just fine except I still have to manually invoke the script. Obviously I don’t want to have to do any more work than I have to, probably like many of you, so I need a way to have my script run “auto-magically.” As it turns out, since I am using a WMI class, there is another option available to me, and that is a WMI event subscription.
Using WMI, you can create a special relationship called an event subscription. As I will show you, creating this in PowerShell is very easy. The primary piece is referred to as the event consumer. This will be PowerShell command that responds to a special type of filter or query. Most event monitoring will use what is referred to as a temporary event consumer. When the process that created the event consumer ends, so does the subscription. The net effect is that when I close my PowerShell session my monitoring also ends. There are ways to create permanent event subscriptions but they are a bit more complicated and more than what I need for my requirements.
To set up the WMI event subscriber, I will need a special type of query. There are several special system classes that are typically used.
List of classes that you will need for the WMI event subscriber. (Image Credit: Jeff Hicks)
"Select * from __InstanceModificationEvent within 60 where TargetInstance ISA 'Win32_Battery'"
The __InstanceModificationEvent class has a property called TargetInstance, which can be the type of object you want to watch. Also note the use of the ISA operator. This is a WMI operatory that is like an equals for classes. But I can also take this query further.
"Select * from __InstanceModificationEvent within 60 where TargetInstance ISA 'Win32_Battery' AND TargetInstance.EstimatedChargeRemaining<=40"
I can create a complex query that will also look at target instance property. In my case, the EstimatedChargeRemaining. My query now says to check every 60 seconds for changes to the Win32_Battery class, where the estimate charge remaining is less than or equal to 40.
When this query returns something, then I want my pop-up script to run. Here’s my script to create this type of event subscription.
#number of seconds to check
$poll = 120
#estimated battery charge remaining threshold
$remaining = 75
$query = "Select * from __InstanceModificationEvent within $poll where TargetInstance ISA 'Win32_Battery' AND TargetInstance.EstimatedChargeRemaining<=$remaining"
#steps to take when a matching event fires
$action={
C:\scripts\watch-battery.ps1 -Limit $remaining -Timeout 10
}
Register-WmiEvent -Query $query -SourceIdentifier "Battery Monitor" -Action $action
When the query gets a result, the code in the $Action scriptblock executes. The Register-WMIEvent cmdlet creates an event subscription. You can see all your subscriptions with Get-EventSubscriber.
Viewing subscriptions with the Get-EventSubscriber cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)
Battery Alert pop-up warning. (Image Credit: Jeff Hicks)
Get-EventSubscriber -SourceIdentifier "Battery Monitor" | Unregister-Event
If you want to use the newer CIM cmdlets, then all you need to do is change the command to create the event subscription.
Register-CimIndicationEvent -Query $query -SourceIdentifier "Battery Monitor" -Action $action
The query remains the same. You will still get an event subscription.
Getting an event subscription in Windows PowerShell. (Image Credit: Jeff Hicks)
The job name is the same as the event source identifier. (Image Credit: Jeff Hicks)
Using Get-EventSubscriber. (Image Credit: Jeff Hicks)
#dot source the create battery watcher event
. C:\scripts\Battery-CIMEvent.ps1
That is plenty permanent enough for me and if I want to change the threshold all I need to do is modify the script and restart PowerShell.
I’ve gone from a simple WMI query to show me how much battery time remains to a simple monitoring tool that offers a graphical interface. I accomplished it all with minimal PowerShell scripting using basic cmdlets and techniques. What tools are you trying to build? If you get stuck, I hope you’ll post in the site’s PowerShell forum.
More in PowerShell
Most popular on petri