Bookmark and Share

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a number of users on our network that use laptops as their primary workstation. These users are constantly complaining that their screen goes dark on them, or that the computer is running slow. I think the problem is the laptops switching between battery and AC power, or maybe the computer sensing that it is idle and switching to a power conservation mode. I know I could probably query the event log to find power management log entries (the laptops are running Windows 7), but I am not sure what entries I should look for, and I do not want to have to weed through hundreds of log entries. Therefore, what I want to know is: Can I use WMI to help me?

-- KB

 

Hey, Scripting Guy! AnswerHello KB,

Microsoft Scripting Guy Ed Wilson here. Today is an absolutely wonderful day. There have been dozens of tweets on Twitter from people who love the Scripting Wife Hey, Scripting Guy! posts I have been writing for the Weekend Scripter. Because of the overwhelming response, I have decided that we’ll run an entire week of Scripting Wife articles the week before the 2010 Scripting Games kickoff on April 26, 2010. There have also been several e-mails to scripter@microsoft.com about the Scripting Wife articles. If that were not enough, I got my supply of ANZAC biscuits and Tim Tams from my buddy Brent. Brent is a TAM (technical account manager—the TAM here has nothing to do with Tim Tam) in Sydney, Australia, and he ensures I do not run out of biscuits.

KB, using WMI eventing, you can obtain information about your laptops switching from full power to minimal power usage. You can also see when your laptops switch from battery power to AC power. To use WMI eventing you will want to use the WMI class Win32_PowerManagementEvent. This is an intrinsic WMI event class, and therefore, you can use it directly with the Register-WMIEvent Windows PowerShell cmdlet.

Note: Yesterday we looked at using a generic WMI Event class, _InstanceCreationEvent, and a regular WMI class, Win32_LogicalDisk, to generate events when a USB drive was inserted into a computer.

To create a WMI event that will monitor for power management events, use the Register-WMIEvent cmdlet and specify the WMI class Win32_PowerManagement. Provide a name like power or something memorable for the SourceIdentifier parameter. The complete command is seen here:

Register-WmiEvent -Class win32_PowerManagementEvent -SourceIdentifier power

After you have registered to receive power management events via WMI, leave the Windows PowerShell console minimized, or continue to use the Windows PowerShell console to do other things. You are not required to devote exclusively the Windows PowerShell console to monitoring for events, but you do need to have the console to receive events. You will not receive a notification when an event is generated unless you use the Get-Event Windows PowerShell cmdlet. When using the Get-Event cmdlet, you need to specify the SourceIdentifier parameter that you created when you used the Register-WmiEvent cmdlet to create the event subscription. This is shown here:

Get-Event -SourceIdentifier power

The Get-Event cmdlet returns a System.Management.Automation.PSEventArgs object for each event that was generated. The members of a System.Management.Automation.PSEventArgs object are seen here:

PS C:\> Get-Event -SourceIdentifier power | Get-Member


   TypeName: System.Management.Automation.PSEventArgs

Name             MemberType Definition
----             ---------- ----------
Equals           Method     bool Equals(System.Object obj)
GetHashCode      Method     int GetHashCode()
GetType          Method     type GetType()
ToString         Method     string ToString()
ComputerName     Property   System.String ComputerName {get;}
EventIdentifier  Property   System.Int32 EventIdentifier {get;}
MessageData      Property   System.Management.Automation.PSObject MessageData {get;}
RunspaceId       Property   System.Guid RunspaceId {get;}
Sender           Property   System.Object Sender {get;}
SourceArgs       Property   System.Object[] SourceArgs {get;}
SourceEventArgs  Property   System.EventArgs SourceEventArgs {get;}
SourceIdentifier Property   System.String SourceIdentifier {get;}
TimeGenerated    Property   System.DateTime TimeGenerated {get;}

When you use the Get-Event cmdlet, all of the returned objects are displayed on the Windows PowerShell console. This is shown in the following image.

Image of all returned objects from Get-Event cmdlet displayed in Windows PowerShell console


What you are really interested in seeing is the information from the NewEvent property of the System.Management.EventArrivedEventArgs object that is returned by the SourceEvent. The NewEvent property contains an instance of a Win32_PowerManagementEvent WMI class. This WMI class is shown here:

PS C:\> $a[1].sourceEventargs.newevent | Get-member


   TypeName: System.Management.ManagementBaseObject#\Win32_PowerManagementEvent

Name                MemberType Definition
----                ---------- ----------
EventType           Property   System.UInt16 EventType {get;set;}
OEMEventCode        Property   System.UInt16 OEMEventCode {get;set;}
SECURITY_DESCRIPTOR Property   System.Byte[] SECURITY_DESCRIPTOR {get;set;}
TIME_CREATED        Property   System.UInt64 TIME_CREATED {get;set;}
__CLASS             Property   System.String __CLASS {get;set;}
__DERIVATION        Property   System.String[] __DERIVATION {get;set;}
__DYNASTY           Property   System.String __DYNASTY {get;set;}
__GENUS             Property   System.Int32 __GENUS {get;set;}
__NAMESPACE         Property   System.String __NAMESPACE {get;set;}
__PATH              Property   System.String __PATH {get;set;}
__PROPERTY_COUNT    Property   System.Int32 __PROPERTY_COUNT {get;set;}
__RELPATH           Property   System.String __RELPATH {get;set;}
__SERVER            Property   System.String __SERVER {get;set;}
__SUPERCLASS        Property   System.String __SUPERCLASS {get;set;}


PS C:\>

To examine one of the events, you can index directly into the collection as shown here:

PS C:\> $a = Get-Event -SourceIdentifier power
PS C:\> $a[1].sourceEventargs.newevent


__GENUS             : 2
__CLASS             : Win32_PowerManagementEvent
__SUPERCLASS        : __ExtrinsicEvent
__DYNASTY           : __SystemClass
__RELPATH           :
__PROPERTY_COUNT    : 4
__DERIVATION        : {__ExtrinsicEvent, __Event, __IndicationRelated, __SystemClass}
__SERVER            :
__NAMESPACE         :
__PATH              :
EventType           : 10
OEMEventCode        :
SECURITY_DESCRIPTOR :
TIME_CREATED        : 129153128712446330



PS C:\>

You can list all of the events, the time they were generated, and the type of event that occurred by piping the result of the Get-Event cmdlet to the Foreach-Object cmdlet. This is shown here:

PS C:\> Get-Event -SourceIdentifier power |
>> Foreach-Object { write-host $_.TimeGenerated $_.sourceEventargs.newevent.eventType }
>>
4/9/2010 2:54:17 PM 10
4/9/2010 2:54:31 PM 10
4/9/2010 3:11:25 PM 10
4/9/2010 3:12:08 PM 10
4/9/2010 3:16:12 PM 4
4/9/2010 3:18:33 PM 7
4/9/2010 3:18:33 PM 18
4/9/2010 3:58:53 PM 10
4/9/2010 3:58:59 PM 10
PS C:\>

 

KB, that is all there is to using WMI events to monitor for power management events. WMI Week will continue tomorrow when we will talk about…wait a minute.

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys