Using Windows PowerShell to Determine if a Laptop Is on Battery Power

ScriptingGuy1

 

Microsoft Scripting Guy Ed Wilson here. It is time for another road trip. This time we are heading to Asheville, North Carolina for the Blue Ridge Classic Horse Show. Somewhere deep in my Scripting Guy lineage is an association with Kentucky, which is considered a horse state. Horse shows are really cool. My significant other and I went to a really cool horse show in Passau Germany a few years ago when I was over on the continent teaching Windows PowerShell classes to Microsoft Premier Customers. While we were at the Apassionata in Passau Germany, we fell in love with Friesen horses. There are several classes at the horse show featuring the Friesen horses, which seem to be appearing more often in the United States of America.

The cool thing is at the arena where the horse show is taking place, there is free wireless Internet access,—therefore I can combine three of my favorite activities all at once. I can write Windows PowerShell scripts on my laptop, take pictures with my digital camera, and hang out on Twitter and on Facebook. Of course, I have a Twitter app and a Facebook app for my Windows Mobile 6.5 Smart Phone, but as long as I have wireless access for my laptop, I would rather use that. Not to mention being able to play with Windows PowerShell.

Anyway, the arena seems to have everything except an abundance of power outlets. Luckily, I brought a spare battery. Nevertheless, this brings up a good question, if I am using Windows PowerShell, how can I tell if my laptop is running on a battery or plugged in? This would be a useful thing to do, if, for example I had detected that I have a laptop computer, and I wanted to kick off an antivirus scan. I just might want to forgo such an operation if the laptop was running on battery.

As it turns out, there are several classes that expose battery information. Oh, wait a second. The horses are lining up for the final judging.

Image of lining up for final judging

Ok, I am back. Dude, I can never seem to guess which horse is going to win. Maybe if I paid more attention to the riders and their horses instead of writing Windows PowerShell scripts I might stand a better chance. Hmm, I wonder if I could write a Windows PowerShell script to pick the winning horse. Maybe something like this:

If($riderSpills -gt 0) {$winner = $false}

Ok, so I can pick the non-winner, but picking the winner is more difficult. Luckily, I know more about picking laptops that are running on battery.

There is a WMI class called Win32_PortableBattery but it does not reveal if the laptop is running on a battery or not. There is also the Win32_Battery WMI class. Here is the information returned by this class. The code seen here uses the gwmi alias for the Get-WmiObject Windows PowerShell cmdlet and relies upon the fact that –class is the first position parameter. In addition, the Get-WmiObject cmdlet assumes the WMI class in question is in the root/cimv2 WMI namespace and that the local computer is the target machine.

PS C:\> gwmi win32_battery
__GENUS : 2
__CLASS : Win32_Battery
__SUPERCLASS : CIM_Battery
__DYNASTY : CIM_ManagedSystemElement
__RELPATH : Win32_Battery.DeviceID=” 1822Panasonic92P1133″
__PROPERTY_COUNT : 33
__DERIVATION : {CIM_Battery, CIM_LogicalDevice, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER : EDWILS1
__NAMESPACE : root\cimv2
__PATH : \\EDWILS1\root\cimv2:Win32_Battery.DeviceID=” 1822Panasonic92P1133″
Availability : 3
BatteryRechargeTime :
BatteryStatus : 1
Caption : Internal Battery
Chemistry : 6
ConfigManagerErrorCode :
ConfigManagerUserConfig :
CreationClassName : Win32_Battery
Description : Internal Battery
DesignCapacity :
DesignVoltage : 10899
DeviceID : 1822Panasonic92P1133
ErrorCleared :
ErrorDescription :
EstimatedChargeRemaining : 19
EstimatedRunTime : 45
ExpectedBatteryLife :
ExpectedLife :
FullChargeCapacity :
InstallDate :
LastErrorCode :
MaxRechargeTime :
Name : 92P1133
PNPDeviceID :
PowerManagementCapabilities : {1}
PowerManagementSupported : False
SmartBatteryVersion :
Status : OK
StatusInfo :
SystemCreationClassName : Win32_ComputerSystem
SystemName : EDWILS1
TimeOnBattery :
TimeToFullCharge :
PS C:\>

There are several properties that are of interest, such as the estimatedChargeRemaining property that reveals I have 19 percent of my battery life remaining, and that that equates to an EstimatedRunTime of 45 minutes. That will give me time to write one more function, take a few pictures, and finish todays Weekend Scripter article. Cool—when I am finished, I will swap batteries. However, unfortunately, there is no information that indicates if the computer is running on battery, or if it is on power. Oh, you are wondering about the batteryStatus property? It reports 1 which means the battery is discharging, but that is not conclusive proof that I am running on battery. Luckily, I can use one more WMI class.

There is a batteryStatus class in the root/wmi WMI namespace. Using the get-wmiobject Windows PowerShell cmdlet, you can retrieve information as seen here.

PS C:\> gwmi -Class batterystatus -Namespace root\wmi
__GENUS : 2
__CLASS : BatteryStatus
__SUPERCLASS : MSBatteryClass
__DYNASTY : CIM_StatisticalInformation
__RELPATH : BatteryStatus.InstanceName=“ACPI\\PNP0C0A\\0_0”
__PROPERTY_COUNT : 20
__DERIVATION : {MSBatteryClass, Win32_PerfRawData, Win32_Perf, CIM_StatisticalInformation}
__SERVER : EDWILS1
__NAMESPACE : root\wmi
__PATH : \\EDWILS1\root\wmi:BatteryStatus.InstanceName=“ACPI\\PNP0C0A\\0_0”
Active : True
Caption :
ChargeRate : 0
Charging : False
Critical : False
Description :
DischargeRate : 20652
Discharging : True
Frequency_Object :
Frequency_PerfTime :
Frequency_Sys100NS :
InstanceName : ACPI\PNP0C0A\0_0
Name :
PowerOnline : False
RemainingCapacity : 25480
Tag : 1
Timestamp_Object :
Timestamp_PerfTime :
Timestamp_Sys100NS :
Voltage : 11009

There are two properties that tell you if the laptop was running on battery power: Discharging or PowerOnline. I think the most accurate property to use would be the PowerOnline property because some advanced battery maintenance routines exercise the battery and therefore could discharge the battery while the laptop was plugged in. To use this in a function, I would do something like the following seen in Test-IsOnBattery.ps1.

Test-IsOnBattery.ps1

Param($computer = “localhost”)
Function Test-IsOnBattery
{
Param(
[string]$computer
)
[BOOL](Get-WmiObject -Class BatteryStatus -Namespace root\wmi `
-ComputerName $computer).PowerOnLine
} #end function test-IsOnBattery
test-isOnBattery -computer $computer

There is only one problem with the Test-IsOnBattery.ps1 script and function –it ain’t supported. Well obviously it is not supported because none of the scripts written in the Hey Scripting Guy! blog or found in the Script Repository are supported—no I mean it really really is not supported … it uses an undocumented WMI class. If a WMI class is not documented, which includes all of the classes in the root\wmi namespace, the class is not supported.

But you know what? If the script works, and if it meets your needs, and if you test it to ensure it meets your needs, then go for it.

Tomorrow we will still be in Asheville as the Horse Show continues. I am thinking about writing a Windows PowerShell script that will detect wireless signal strength. It will be cool if it works. Check back tomorrow, and I will let you know how it turns out. In the meantime, I will be looking for you on Twitter or Facebook. If you have any questions, shoot us an email at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson and Craig Liebendorfer, Scripting Guys

0 comments

Discussion is closed.

Feedback usabilla icon