10

On Windows 10 (among other versions) running on a device having a battery, I can use powercfg /batteryreport to obtain the "Design Capacity" and "Last Full Charge Capacity" for the battery, which give an idea of the remaining useful service life of the battery and how much its capacity has degraded from use.

C:\Users\superuser\AppData\Local\Temp>powercfg /batteryreport
Battery life report saved to C:\Users\superuser\AppData\Local\Temp\battery-report.html

The HTML report is generated instantaneously and displays, among others, the statistics I'm interested in:

powercfg battery report showing design capacity and full charge capacity

Moreover, I can boot into this laptop's built-in diagnostic environment and it displays similar figures, and the discharge cycle count of the battery.

From where are these values being obtained? I would like to be able to track this battery life data over time for a fleet of laptops, preferably from a Powershell script. It seemed likely that this data should be in WMI, and sure enough, there's a Win32_Battery class having DesignCapacity and FullChargeCapacity fields, but on all the systems I have tested, they are undefined:

PS C:\Users\superuser> Get-WmiObject -Class Win32_Battery | Select-Object -Property *Capacity | Format-List


DesignCapacity     :
FullChargeCapacity :

There must be some programmatic way to access this information, because powercfg is doing it. If there is some WMI, .NET, or Powershell way to do this, I'd like to know about it. I could generate the powercfg report and then parse it, but I really don't want to implement an ugly workaround when there is most likely a "right" way to do it that is just escaping me.

5
  • well, the windows is able to retrieve that information from the system firmware (BIOS/UEFI) via the ACPI: acpi.info en.wikipedia.org/wiki/… Oct 31, 2015 at 3:52
  • +1 good question. I hate it when stuff isn't in WMI or not wrapped by PowerShell.
    – David Betz
    Oct 31, 2015 at 6:21
  • This capitalization trend is getting ridiculous. LION CHEMISTRY! Nov 2, 2015 at 17:16
  • Ah, the "CHEMISTRY" in the HTML reports (black boxes) say LION, presumably referring to Lithium Ion. It took me a while to comprehend just what @beatcracker's comment was saying.
    – TOOGAM
    Nov 3, 2015 at 1:26
  • @TOOGAM So, it's just me, then :). Still, I want a RACOON CHEMISTRY in my laptop battery, so it would grab whatever power source it could find. Nov 3, 2015 at 2:38

2 Answers 2

7

It looks like you have to dig into MSBattery super class:

A number of the classes in root\wmi return results from more than one class. That sounds odd but it can be explained by an example.

The namespace contains a number of classes related to the battery in laptops

gwmi -Namespace root\wmi -List *battery*

MSBatteryClassEvent
BatteryStatusChange
BatteryTagChange 
MSBatteryClass
BatteryStaticData
BatteryRuntime
BatteryCycleCount 
BatteryTemperature
BatteryStatus
BatteryFullChargedCapacity

We’ll ignore the event and change classes for now. If we pick out the MSBattery class we get information from a number of other classes returned – MSBattery is a super class.

PS> gwmi -Namespace root\wmi -Class MSBatteryClass | select __class

__CLASS  ——-
BatteryCycleCount
BatteryFullChargedCapacity
BatteryStaticData
BatteryRuntime BatteryStatus

Examples, that kind of work on my laptop:

Get-WmiObject -Namespace 'root\wmi' -Query 'select DeviceName, ManufactureName, Chemistry, DesignedCapacity from BatteryStaticData'

__GENUS          : 2
__CLASS          : BatteryStaticData
__SUPERCLASS     : 
__DYNASTY        : 
__RELPATH        : 
__PROPERTY_COUNT : 4
__DERIVATION     : {}
__SERVER         : 
__NAMESPACE      : 
__PATH           : 
Chemistry        : 1852787020
DesignedCapacity : 48400
DeviceName       : K52F-44
ManufactureName  : ASUSTek
PSComputerName   : 


Get-WmiObject -Namespace 'root\wmi'  -Query 'select FullChargedCapacity  from BatteryFullChargedCapacity'

__GENUS             : 2
__CLASS             : BatteryFullChargedCapacity
__SUPERCLASS        : 
__DYNASTY           : 
__RELPATH           : 
__PROPERTY_COUNT    : 1
__DERIVATION        : {}
__SERVER            : 
__NAMESPACE         : 
__PATH              : 
FullChargedCapacity : 47157
PSComputerName      : 


Get-WmiObject -Namespace 'root\wmi'  -Query 'select CycleCount from BatteryCycleCount'

__GENUS          : 2
__CLASS          : BatteryCycleCount
__SUPERCLASS     : 
__DYNASTY        : 
__RELPATH        : 
__PROPERTY_COUNT : 1
__DERIVATION     : {}
__SERVER         : 
__NAMESPACE      : 
__PATH           : 
CycleCount       : 0
PSComputerName   : 

Why kind of? Because while you can see that DesignedCapacity, FullChargedCapacity and CycleCount have some values, powercfg /batteryreport doesnt recoginze them:

Battery stats

2

Here is a simple WMI "crawler" that combines all battery-classes into one object:

# get battery-identifier:
$batteryClass = Get-WmiObject -Namespace root\WMI -Class MSBatteryClass
if (!$batteryClass) {'this device has no physical battery.'; break}
$batteryData = foreach ($entry in $batteryClass) {
    if ($entry.UniqueID) {$entry | select UniqueID, InstanceName}
}

# find data based on the UniqueID of the battery:
foreach ($entry in Get-wmiobject Win32_battery) {
    $battery = @($batteryData).where{$_.UniqueID -eq $entry.DeviceID}
    $attribs = $entry | Get-Member | ?{$_.MemberType -eq 'Property' -and !$_.name.startswith('__')}
    foreach ($a in $attribs.name) {
        $battery | Add-Member -Name "Win32_battery.$a" -Value $entry.$a -MemberType NoteProperty
    }
}

# find data based on the InstanceName of the battery:
foreach ($class in $batteryClass.__CLASS | select -Unique) {
    $classData = Get-WmiObject -Namespace root\WMI -Class $class
    foreach ($entry in $classData) {
        $battery = @($batteryData).where{$_.InstanceName -eq $entry.InstanceName}
        $attribs = $entry | Get-Member | ?{$_.MemberType -eq 'Property' -and !$_.name.startswith('__')}
        foreach ($a in $attribs.name) {
            $battery | Add-Member -Name "$class.$a" -Value $entry.$a -MemberType NoteProperty
        }
    }
}

$battery

Unfortunaltely the WMI-classes do not translate all values into readable format (e.g. chemistry is just a value but not a string) and also not any runtime estimation for the fully charged battery. That one comes from the history of all charg/discharge events into the powercfg-report.

2
  • You verified these examples worked within a VM?
    – Ramhound
    Feb 6, 2021 at 19:39
  • VMs dont have a physical battery and no class "MS_battery". I added one line for error-handling in the snippet.
    – Carsten
    Feb 7, 2021 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.