batteryreport XMLで満充電容量94.1%を測った
powercfg /batteryreport /XML から取れた満充電容量は48450mWhで、設計容量51480mWhに対して94.1%だった。
ARM64 機の売りとしてバッテリー持ちは外せない。Surface Pro 11th Edition を触っていると、起動時間やエミュレーションの速度よりも、最後は電池がどれだけ残るかのほうが効いてくる場面がある(外で使う日は特にそう感じる)。そこで今回は体感ではなく、Windows が持っている batteryreport の XML から劣化率を数字で出してみた。測定日は2026年7月12日。
HTML レポートを目で読む必要がなかったのは、少し予想と違っていた。/XML を付けると DesignCapacity と FullChargeCapacity がタグとして出てくる。正規表現で抜けば、メモに貼る数字を手で転記しなくて済む(桁を読み間違える心配も減る)。逆に、日ごとの使用履歴は同じ調子では取れていない(HTML を目で読む前提から少し外れた)。entry_count は0件で、entries_sample も空だった。
XML から容量だけ抜く
実際に試したコマンドは powercfg /batteryreport /XML で、出力先は XML ファイルにしている。HTML の表を眺める方法もあるが、記事にするなら機械的に同じ値を再取得できるほうがよいだろう。
今回の抽出は、XML 全体を文字列として読み、必要なタグだけを正規表現で拾っている(容量タグだけなら思ったより素直だった)。PowerShell でも XML パーサーでもよいけれど、まずはどのタグを取ればよいかを確認したかったので、最小限の処理にした(ここを横着したことが、履歴側ではそのまま失敗につながる)。
$xml = Get-Content .\batteryreport.xml -Raw
$design = [int]([regex]::Match($xml, '<DesignCapacity>(\d+)</DesignCapacity>').Groups[1].Value)
$full = [int]([regex]::Match($xml, '<FullChargeCapacity>(\d+)</FullChargeCapacity>').Groups[1].Value)
$health = [math]::Round($full / $design * 100, 1)
この形だと、ブラウザで battery report を開いて、表の場所を探して、桁を読み間違えないようにコピーする、という作業が消える。手元では XML 生成自体も6.53秒で終わっている。記事用の測定としては、十分に軽い感じ。
取れた容量と取れなかった履歴
取れた値をそのまま置く。数値は JSON に残っていたものだけを使っている。
| 項目 | 値 |
|---|---|
| XML 生成時間 | 6.53秒 |
| XML サイズ | 154155bytes |
| 設計容量 DesignCapacity | 51480mWh |
| 満充電容量 FullChargeCapacity | 48450mWh |
| 差分 | 3030mWh |
| 健康度 | 94.1% |
| 使用履歴 entry_count | 0件 |
| WMI 取得時間 | 1.13秒 |
| EstimatedChargeRemaining | 80% |
| DesignVoltage | 8221mV |
| powerplan 取得時間 | 0.32秒 |
計算は単純で、48450 / 51480 * 100 を小数1桁に丸めて94.1%。差分は51480mWhから48450mWhを引いた3030mWhになる。満充電の器が新品時より3030mWhぶん小さくなっている、という読み方をしている(ここまでは batteryreport XML だけで完結する)。
WMI 側では Win32_Battery の stdout に JSON 文字列が入っていた。中身は Name が SurfaceBattery、EstimatedChargeRemaining が80、DesignVoltage が8221、BatteryStatus が2。batteryreport XML の容量とは別系統の確認として、現在の残量と設計電圧が取れている(履歴側の正規表現がかなり甘かった)。
電源プランは 381b4222-f694-41f0-9685-ff5bb260df2e (バランス) だった。既定の「バランス」で動いているので、今回の batteryreport 生成は高パフォーマンス側に振った状態ではない(なぜ履歴だけ空なのか、後で気になった)。
使用履歴は抜けなかった
ここは失敗している。短く言えば、0件という結果。
entry_count は0件、entries_sample は空配列だった。指示としては日ごとの使用履歴から開始日時、アクティブ時間、消費エネルギーを取り、1時間あたりの消費 mWh を計算する計画にしていたところ(次は XML ノードを見て取り直す)。取れていれば、48450mWhをその消費量で割って、満充電から何時間もつ見込みになる(WMI と batteryreport を混ぜすぎないようにした)。なぜ容量タグは取れたのに履歴だけ空になったのか。
今回はそれができなかった。正直に言うと、正規表現が想定した属性名と実際の XML の形が合っていなかった可能性が高い。容量のタグは取れたのに、履歴側だけ0件になっているので、batteryreport に履歴がないと断定するより、抽出スクリプトの見方が狭かったと考えるほうが自然だろう。
この失敗はむしろ記事に残しておく価値がある。バッテリーの健康度だけなら DesignCapacity と FullChargeCapacity の2個で済む。けれど使用履歴まで見るなら、タグ名だけでなく属性名や階層を実際の XML に合わせて読む必要がある(外で使う日の体感とはまだ別の話だ)。HTML では表に見えていても、XML 側で同じ名前とは限らない(健康度だけで持ち時間まで語りかけていた)。
劣化率だけなら動いた
健康度を測る用途では動いた。powercfg /batteryreport /XML を出し、2つの容量タグを抜き、94.1%という数字に落とすところまでは再現しやすい。ARM64 Windows だから特別な手順が必要だったわけでもなく、ここだけなら拍子抜けするくらい短い作業だった。
ただし、今回の verdict は「条件つき」にした。理由は使用履歴が0件だったからだ。バッテリー持ちを語るなら、本当は「満充電容量が48450mWhある」だけでは足りない。実際に1時間で何mWh減るのかまで取れて、初めて「この使い方なら何時間くらい」という話になる。
手元では、まず劣化率を見るための小さい道具として使うのがよさそうだ。中古機を買った直後、長く使った端末の状態確認、OS 更新後に満充電容量が急に変わっていないかを見る(容量タグだけなら思ったより素直だった)。そういう確認なら、HTML を開かず XML だけで足りるはず(履歴側の正規表現がかなり甘かった)。
個人的には、バッテリー持ちを売りにする ARM64 機ほど、この数字をたまに見たほうがよいと感じた(健康度だけで持ち時間まで語りかけていた)。体感で「今日は減りが早い」と思っても、満充電容量が落ちたのか、使い方が重かったのか、電源プランが変わったのかは分けて考えたい。
次に直すところ
次にやるなら、使用履歴の抽出を正規表現だけで押し切らず、XML のノード構造を見てから取り直す(HTML を目で読む前提から少し外れた)。entry_count が0件のままだと、消費エネルギーから稼働時間を出す話に進めないので、まず一件でも履歴を拾える形に直してみる。
それでも、今回の小さい確認だけで分かったことはある。2026-07-12 の測定では、SurfaceBattery の満充電容量は48450mWh、設計容量との差は3030mWh、健康度は94.1%。電源プランはバランス。ここまでは機械的に取れた。
意外だったのは、バッテリーの状態確認が思っていたより短いコードで済んだことだ。ハマったのは履歴側で、そこはまだ宿題として残る。次は XML の実際の形に合わせて、使用履歴を1件でも抜けるところからやり直したい。