Hey, Scripting Guy! How can I tell whether a laptop computer is running off batteries?
Hey, TJ. Ah, yes: batteries. Back in December the Scripting House lost power for six days. Was the Scripting Guy who writes this column concerned? Of course not. After all, he was fully prepared for an emergency like that: he had four (count ‘em: four) flashlights, each one fully-stocked with batteries. Granted, he had no way to heat the house, and after a day without power all the food (or at least the food in the refrigerator) had to be thrown out. But he did have four flashlights, fully-stocked with batteries.
About the only thing he wasn’t prepared for was the fact that batteries don’t maintain their charge forever. (Hey, who knew?) Within a day two of his four flashlights had already died; shortly thereafter the other two began to sputter and cough. At that point the Scripting Guy who writes this column sat down on the floor, disassembled all the flashlights, and started mixing and matching batteries in the hope of finding some combination that would enable at least one of the flashlights to continue working.
What’s that? Just walk down to the store and buy some new batteries? Actually the Scripting Family did walk down to the store one day, mainly because there wasn’t anything to do at home. Although most businesses were closed (they didn’t have power, either) one of the grocery stores was sort of open; as you entered the store they gave you a lantern so you could make your way through the darkened aisles, just in case someone overlooked a box of crackers or something. The Scripting Guy who writes this column wandered into the store just to see if they happened to have any batteries. Not only was every single battery of every single size long-since gone, but the battery area looked like a war zone: apparently people had gone into the store, torn the batteries from the package, and then (we assume) took them without even paying for them.
But who can blame them? After all, two days without a cappuccino will drive anyone insane.
At any rate, trying to find some combination of batteries that would make a flashlight work was an interesting exercise, an exercise very similar to your question, TJ: trying to determine whether a laptop computer is running off of batteries. As it turns out, there are millions of WMI classes in the cimv2 namespace that say they will return information about batteries; however, those classes proved to be a bit disappointing, to say the least. For example, on the Scripting Test Machine the Win32_PortableBattery class returned no information whatsoever. By contrast, the Win32_Battery class did return information … sort of. To note two instances, the BatteryStatus and Availability classes seemed to randomly return one of two values: Unknown or Other.
Note. What’s the difference between Unknown and Other? Good question. As near as we can tell, Unknown means, “We have no idea what the battery status is.” By contrast, Other apparently means, “We know what the battery status is. But we aren’t going to tell you.” Either way the information wasn’t particularly helpful.
It was at this point that the Scripting Guy who writes this column started poking through the root\wmi namespace. Poking through the root\wmi namespace is a lot like going to a second-hand store: most of what you find is of no use to you whatsoever. (The majority of classes stashed in root\wmi are valid classes, but they don’t return any data.) Every now and then, however, you stumble upon something a little more valuable. At a second-hand store this might be a long-lost copy of the Declaration of Independence; in the root\wmi namespace, this might be the BatteryStatus class:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
Set colItems = objWMIService.ExecQuery("Select * From BatteryStatus Where Voltage > 0")
For Each objItem in colItems
Wscript.Echo "Battery: " & objItem.InstanceName
Wscript.Echo "On AC Power: " & objItem.PowerOnline
Wscript.Echo "Battery is Discharging: " & objItem.Discharging
Wscript.Echo "Battery is Charging: " & objItem.Charging
Wscript.Echo "Remaining capacity: " & objItem.RemainingCapacity
One caveat before we explain how this script works. As far as we know this particular class has never been documented; we searched everywhere for additional information on the BatteryStatus class and couldn’t find much of anything. However, as near as we can tell the script works just fine on laptops running either Windows XP or Windows Vista, so, with any luck, this will get you started, TJ.
Note. Does the script run on other versions of Windows? To tell you the truth, we don’t know; that’s because we don’t have any laptops running, say, Windows 2000 or Windows Server 2003.
As for the script itself, we begin by binding to the WMI service on the local computer. Fortunately this script also works remotely; after all, if you want to know if the local computer is running off batteries it’s probably quicker and easier just to see whether or not the power cord is plugged into the wall. So then how do you modify this script to run against a remote machine? That’s easy; just assign the name of the remote computer (e.g., atl-ws-01) to the variable strComputer:
strComputer = "atl-ws-01"
After making the connection (note that we bind to the root\wmi namespace) we then use this line of code to retrieve information about all the batteries with a Voltage greater than 0:
Set colItems = objWMIService.ExecQuery("Select * From BatteryStatus Where Voltage > 0")
Why did we add the stipulation about batteries with a voltage greater than 0? Well, to tell you the truth, we aren’t sure if that’s required or not. In our case the Scripting Test Machine has two separate battery bays; being a cheapskate, however, the Scripting Guy who writes this column only has one battery installed in the computer. Nevertheless the empty bay gets reported back as a battery, albeit a battery with a voltage of 0. That seemed silly to us, so we added the Where clause to filter out non-existent batteries.
Note. Yes, when trying to determine which flashlight batteries worked and which ones didn’t the Scripting Guy who writes this column should have done something similar, carefully setting aside batteries that he knew did not work. The one thing he shouldn’t have done is test a battery and then simply toss it back on the pile, mixing it in with the batteries that he hadn’t tested. So is this what he did? Well, you know, that was a long time ago, and it’s hard to remember what he did or didn’t do ….
After executing our query we then set up a For Each loop to report back information for each battery in the collection. We chose to echo back values for the following properties:
InstanceName. Identifying information for the battery.
PowerOnline. The key to this entire script. If PowerOnline is True that means that the AC adapter is plugged in and the computer is not running off the battery. If PowerOnline is False that means that the computer is running off the battery.
Discharging. Indicates whether the battery is in use and therefore discharging.
Charging. Indicates whether the battery is currently charging.
RemainingCapacity. Lets you know the estimated battery life. We’re not 100% sure what this number means. We found some information that suggests the value is reported back as milliwatt-hours, but we don’t know that for sure; for that matter, we don’t even know what a millwatt-hour is. However, we do know this: on our test computer the Windows Power Meter would report an estimated battery life like 2 hours and 54 minutes (that is, 174 minutes). Meanwhile, the value of the RemainingCapacity property would come back as 43734. If we divided 43734 by 174 minutes, we got back a value of 252. For us 252 seemed to be the magic number: any time we divided RemainingCapacity by 252 we got back a value, in minutes, that matched up quite nicely with the estimated battery life reported back by the Power Meter. Again, we can’t guarantee that 252 is the magic number but, again, it gives you a place to start.
So what happens when we unplug the test machine (causing it to run off the battery) and then fire up the script? Why, we get back information similar to this:
On AC Power: False
Battery is Discharging: True
Battery is Charging: False
Remaining capacity: 41769
And if we then plug the computer in and try the script again we get back information similar to this:
On AC Power: True
Battery is Discharging: False
Battery is Charging: True
Remaining capacity: 42273
In other words, and unlike the typical Scripting Guy flashlight, the script appears to work just fine.
Speaking of flashlights, once the stores were reopened and the shelves restocked did the Scripting Guy who writes this column go out and replenish his supply of batteries? Let’s put it this way: remember the fable about the grasshopper and the ant, the story where the ant worked hard to store up food for the winter while the grasshopper spent his time singing and dancing? To be honest, we don’t know much about this particular fable; we were too busy singing and dancing to finish reading it. But we’re sure that, somehow, the grasshopper magically ended up with all the food and batteries he needed to get him through the winter.
At least we hope he did.