`powercfg` 从哪里获取电池健康信息,为什么不在 WMI 中?

`powercfg` 从哪里获取电池健康信息,为什么不在 WMI 中?

在运行 Windows 10(以及其他版本)且带有电池的设备上,我可以使用它powercfg /batteryreport来获取电池的“设计容量”和“上次完全充电容量”,从而了解电池的剩余使用寿命以及其容量因使用而下降了多少。

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

HTML 报告会立即生成,并显示我感兴趣的统计信息:

powercfg 电池报告显示设计容量和满充电容量

此外,我可以启动这台笔记本电脑的内置诊断环境,它会显示类似的数字和电池的放电循环次数。

这些值是从哪里获得的?我希望能够跟踪笔记本电脑的电池寿命数据,最好是通过 Powershell 脚本。这些数据似乎应该在 WMI 中,果然,有一个Win32_Battery 类具有DesignCapacityFullChargeCapacity字段,但在我测试过的所有系统上,它们都是未定义的:

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


DesignCapacity     :
FullChargeCapacity :

必须有某种编程方式来访问此信息,因为powercfg正在这样做。如果有某种 WMI、.NET 或 Powershell 方式可以做到这一点,我很想知道。我可以生成报告powercfg然后解析它,但我真的不想实现一个丑陋的解决方法,因为很可能有一种“正确”的方法来做到这一点,而我却想不起来。

答案1

看来你必须深入研究MSBattery 超类

root\wmi 中的许多类都返回来自多个类的结果。这听起来很奇怪,但可以通过一个例子来解释。

该命名空间包含许多与笔记本电脑电池相关的类

gwmi -Namespace root\wmi -List *battery*

MSBatteryClassEvent
BatteryStatusChange
BatteryTagChange 
MSBatteryClass
BatteryStaticData
BatteryRuntime
BatteryCycleCount 
BatteryTemperature
BatteryStatus
BatteryFullChargedCapacity

现在我们将忽略事件并更改类。如果我们选择 MSBattery 类,我们将从返回的许多其他类中获取信息 - MSBattery 是一个超类。

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

__CLASS  ——-
BatteryCycleCount
BatteryFullChargedCapacity
BatteryStaticData
BatteryRuntime BatteryStatus

例如,在我的笔记本电脑上进行此类工作:

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   : 

为什么?因为虽然你可以看到DesignedCapacityFullChargedCapacity并且CycleCount拥有一些值,powercfg /batteryreport但却无法识别它们:

电池状态

答案2

这是一个简单的 WMI“爬虫”,它将所有电池类别组合成一个对象:

# 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

不幸的是,WMI 类不会将所有值转换为可读格式(例如,化学性质只是一个值,而不是字符串),也不会对充满电的电池进行任何运行时估计。该估计来自 powercfg-report 中所有充电/放电事件的历史记录。

相关内容