Choosing Best File Format (Part 4)

by Jul 7, 2023

In the previous parts, we reviewed different file types to persist data and cmdlets to read and write them.

Today, let’s apply this to a real-world data file that you can create yourself (provided you own a battery-driven notebook with Windows on it):

$Path = "$env:temp\battery.xml"
powercfg.exe /batteryreport /duration 1 /output $path /xml 

Once you run this line, it produces an XML file with all of your battery information, including its design capacity and its real capacity, so you can find out whether your battery is still in shape. Take the appropriate code example from the previous parts to read in the XML file:

# path to XML file:
$Path = "$env:temp\battery.xml"

# read file and convert to XML:
[xml]$xml = Get-Content -Path $Path -Raw -Encoding UTF8  

Next, explore the object structure of the XML you got in $xml by adding “.” in your favorite editor, and look at IntelliSense or by simply outputting the variable, in which case PowerShell prints the next level property names.

This way, I am finding my way to the battery capacity information:

PS> $xml

xml                            xml-stylesheet                                   BatteryReport
---                            --------------                                   -------------
version="1.0" encoding="utf-8" type='text/xsl' href='C:\battery-stylesheet.xsl' BatteryReport

PS> $xml.BatteryReport

xmlns             : http://schemas.microsoft.com/battery/2012
ReportInformation : ReportInformation
SystemInformation : SystemInformation
Batteries         : Batteries
RuntimeEstimates  : RuntimeEstimates
RecentUsage       : RecentUsage
History           : History
EnergyDrains      : 

PS> $xml.BatteryReport.Batteries
Battery
-------
Battery

PS> $xml.BatteryReport.Batteries.Battery

Id                 : DELL XX3T797
Manufacturer       : BYD
SerialNumber       : 291
ManufactureDate    : 
Chemistry          : LiP
LongTerm           : 1
RelativeCapacity   : 0
DesignCapacity     : 49985
FullChargeCapacity : 32346
CycleCount         : 0 

Now we can put together all parts into a script that returns object-oriented battery wear information (make sure your system has batteries, or else you get red exceptions):

# temp path to XML file:
$Path = "$env:temp\battery$(Get-Date -Format yyyyMMddHHmmssffff).xml"
# generate XML file
powercfg.exe /batteryreport /duration 1 /output $path /xml
# read file and convert to XML:
[xml]$xml = Get-Content -Path $Path -Raw -Encoding UTF8 
# remove temporary file:
Remove-Item -Path $Path
# show battery infos:
$xml.BatteryReport.Batteries.Battery 

With just very little effort, the same can become a helpful new command:

function Get-BatteryCapacity
{
    # temp path to XML file:
    $Path = "$env:temp\battery$(Get-Date -Format yyyyMMddHHmmssffff).xml"
    # generate XML file
    powercfg.exe /batteryreport /duration 1 /output $path /xml
    # read file and convert to XML:
    [xml]$xml = Get-Content -Path $Path -Raw -Encoding UTF8 
    # remove temporary file:
    Remove-Item -Path $Path
    # show battery infos:
    $xml.BatteryReport.Batteries.Battery
} 

Now it’s easy to check battery wear:

PS> Get-BatteryCapacity | Select-Object Id, Manufacturer, FullChargeCapacity, DesignCapacity

Id           Manufacturer FullChargeCapacity DesignCapacity

--           ------------ ------------------ --------------
                                                           
DELL XX3T797 BYD          32346              49985         

Using hash tables, Select-Object can now even calculate the remaining battery capacity in percent (but that is another topic that we won’t dive deeper today):

PS> Get-BatteryCapacity | Select-Object Id, Manufacturer, FullChargeCapacity, @{N='Remain';E={'{0:P}' -f ($_.FullChargeCapacity/$_.DesignCapacity)}}
Id           Manufacturer FullChargeCapacity Remain 
--           ------------ ------------------ ------ 
                                    
DELL XX3T797 BYD          32346              64,71 %