Detecting Laptop Battery Wear

Listen to this blog post!

Table of contents:

Laptop and notebook batteries wear out over time, just like any other battery. When your laptop’s battery runtime seems to shorten, it might be a good idea to check whether your battery is still in good shape. There’s no obvious place or command to find battery degradation status. However, PowerShell can combine a few WMI techniques to retrieve this information:

$designCap = Get-WmiObject -Class 'BatteryStaticData' -Namespace 'root\wmi' | 
Group-Object -Property InstanceName -AsHashTable -AsString
    
Get-CimInstance -Class 'BatteryFullChargedCapacity' -Namespace 'root/wmi' | 
Select-Object -Property InstanceName, FullChargedCapacity, DesignedCapacity, Percent |
ForEach-Object {
	$_.DesignedCapacity = $designCap[$_.InstanceName].DesignedCapacity
	$_.Percent = [Math]::Round( ( $_.FullChargedCapacity * 100 / $_.DesignedCapacity), 2)
	$_
} 

When you run this code, the result may look like this:

InstanceName     FullChargedCapacity DesignedCapacity Percent
------------     ------------------- ---------------- -------
ACPI\PNP0C0A\1_0               26486            49985   52,99 

You see the original design capacity and the remaining battery capacity. These values are unrelated to the charging status; they describe how worn down the battery is.

In the example output, the laptop battery is at 52.99% of its original capacity, indicating it’s definitely time to replace the battery.

Note that the code uses the older Get-WmiObject cmdlet for the first WMI query. This is intentional: for unknown reasons, this information can only be retrieved using Get-WmiObject, not the modern Get-CimInstance. PowerShell 7 transparently proxies Get‑WmiObject via implicit remoting, causing the cmdlet to execute in a Windows PowerShell process and return its results to PowerShell 7 session.

Wrapped as a Function

Here is the same code wrapped as a PowerShell function:

function Test-Battery
{
    $designCap = Get-WmiObject -Class 'BatteryStaticData' -Namespace 'root\wmi' | 
    Group-Object -Property InstanceName -AsHashTable -AsString
    
    Get-CimInstance -Class 'BatteryFullChargedCapacity' -Namespace 'root/wmi' | 
    Select-Object -Property InstanceName, FullChargedCapacity, DesignedCapacity, Percent |
    ForEach-Object {
	    $_.DesignedCapacity = $designCap[$_.InstanceName].DesignedCapacity
	    $_.Percent = [Math]::Round( ( $_.FullChargedCapacity * 100 / $_.DesignedCapacity), 2)
	    $_
    }
} 

Once you define the function (or add it to a module), you can simply run:

PS C:\> Test-Battery

InstanceName     FullChargedCapacity DesignedCapacity Percent
------------     ------------------- ---------------- -------
ACPI\PNP0C0A\1_0               26486            49985   52,99

Note: If your computer has more than one built‑in battery, you’ll see information for each battery, and the command will output multiple objects.

Related links