Many years ago when Windows Vista was introduced, it came with new GUI effects like transparency (called “Aero”), and at that time computer hardware wasn’t always capable of supporting these. That’s why Microsoft invented the Windows Experience Index and an assessment tool that calculates the performance of your hardware.
Initially, this assessment tool was used to ensure that computer hardware was capable of supporting advanced GUI tricks. Today, any hardware can handle 3D effects, so the experience index was removed from dialogs. Yet, the assessment engine is still there, and you can use it to calculate and test your computer hardware and compare it to other systems.
Accessing Hardware Performance Data
PowerShell can easily retrieve the hardware performance indices of your machine. The WMI class Win32_WinSAT queries the performance data:
Get-CimInstance -ClassName Win32_WinSAT
You get back an object with the scores for various hardware subsystems:
CPUScore : 8,9
D3DScore : 9,9
DiskScore : 8,75
GraphicsScore : 8
MemoryScore : 8,9
TimeTaken : MostRecentAssessment
WinSATAssessmentState : 1
WinSPRLevel : 8
PSComputerName :
The score is a cooked number between 0 and 10. To retrieve the actual raw technical performance data, you need to access XML files directly that were created by a tool named WinSAT.exe.
Accessing Raw Performance Data
All assessments are created by WinSAT.exe. This command line tool requires Administrator privileges. When you run the tool without Administrator privileges, it auto-elevates itself in a new window and closes again immediately. So make sure you run the following examples with an elevated PowerShell host.
Dumping Raw Assessments
To get a quick overview of the current assessments, use the parameter query:
winsat query
This outputs the data as text:
Windows System Assessment Tool
> Run Time 00:00:00.00
> CPU LZW Compression 473.49 MB/s
> CPU AES256 Encryption 7352.66 MB/s
> CPU Vista Compression 1147.18 MB/s
> CPU SHA1 Hash 2157.81 MB/s
> Uniproc CPU LZW Compression 92.76 MB/s
> Uniproc CPU AES256 Encryption 1099.06 MB/s
> Uniproc CPU Vista Compression 229.82 MB/s
> Uniproc CPU SHA1 Hash 660.36 MB/s
> Memory Performance 39903.06 MB/s
> Dshow Video Encode Time 0.00000 s
> Dshow Video Decode Time 0.00000 s
> Media Foundation Decode Time 0.00000 s
> Disk Sequential 64.0 Read 2377.30 MB/s 9.1
> Disk Random 16.0 Read 619.60 MB/s 8.4
Obviously, while this is ok for a quick read, it won’t help much when you plan to read the data in an automated way.
Directly Accessing XML Data
WinSAT.exe stores the assessment data in various XML files in this folder:
explorer 'C:\Windows\Performance\WinSAT\DataStore'
The files come with a timestamp and a description of the hardware tests. Windows performs an automatic initial assessment when you install it. These initial assessments are marked with (Initial). If you recalculated the index later, additional files may be present.
Name Length
---- ------
2019-09-14 09.39.31.893.winsat.etl 98304
2019-09-14 09.39.33.309 Cpu.Assessment (Initial).WinSAT.xml 58668
2019-09-14 09.39.33.309 Disk.Assessment (Initial).WinSAT.xml 51196
2019-09-14 09.39.33.309 DWM.Assessment (Initial).WinSAT.xml 10910
2019-09-14 09.39.33.309 Graphics3D.Assessment (Initial).WinSAT.xml 40334
2019-09-14 09.39.33.309 Mem.Assessment (Initial).WinSAT.xml 9700
2019-09-14 09.41.06.573 Formal.Assessment (Initial).WinSAT.xml 146108
The file(s) starting with Formal contain a summary of all assessments. To get to the latest assessments for your system, simply pick the latest xml file that starts with Formal:
# get the freshest file that starts with "Formal" from the WinSAT datastore:
$path = Get-ChildItem -Path 'C:\Windows\Performance\WinSAT\DataStore\*Formal.*.xml' | Sort-Object -Property CreationTime -Descending | Select-Object -First 1 -ExpandProperty FullName
Examining XML Content
The file contains XML data and looks similar to this:
Start-Process -FilePath iexplore -ArgumentList $Path
I am using the ancient Internet Explorer to visualize the XML content. It’s the easiest way of getting a quick overview of the nested nodes because Internet Explorer automatically prettifies the raw XML and adds appropriate indentation and line breaks.
Here is a nice trick that you can use to prettify XML in the PowerShell console:
# get the freshest file that starts with "Formal" from the WinSAT datastore: $path = Get-ChildItem -Path 'C:\Windows\Performance\WinSAT\DataStore\*Formal.*.xml' | Sort-Object -Property CreationTime -Descending | Select-Object -First 1 -ExpandProperty FullName # read the file content $content = Get-Content -Path $Path -Raw # the default output looks aweful: $content # prettify it: ([xml]$content).Save([Console]::Out)
Reading XML Content
The easiest and fastest way to process XML content is to load it directly into an XML object via its method Load(). Next, you can output the nodes you are after in object-oriented fashion:
# get the freshest file that starts with "Formal" from the WinSAT datastore:
$path = Get-ChildItem -Path 'C:\Windows\Performance\WinSAT\DataStore\*Formal.*.xml' | Sort-Object -Property CreationTime -Descending | Select-Object -First 1 -ExpandProperty FullName
# load xml content
$xml = [xml]::new()
$xml.Load($Path)
# access node with data:
$xml.WinSAT.Metrics.CPUMetrics.CompressionMetric
The result is outputted as objects:
units #text
----- -----
MB/s 473.49160
To access the compression rate, try this:
# access node with data:
$node = $xml.WinSAT.Metrics.CPUMetrics.CompressionMetric
'CPU Compression Performance is {0} {1}' -f $node.'#text', $node.units
Investigating Hardware
The xml data produced by WinSAT.exe does not only contain performance data. It also provides important details about your computer hardware. The hardware details can be found in WinSAT.SystemConfig:
# get the freshest file that starts with "Formal" from the WinSAT datastore:
$path = Get-ChildItem -Path 'C:\Windows\Performance\WinSAT\DataStore\*Formal.*.xml' | Sort-Object -Property CreationTime -Descending | Select-Object -First 1 -ExpandProperty FullName
# load xml content
$xml = [xml]::new()
$xml.Load($Path)
# access node with data:
$xml.WinSAT.SystemConfig
You’ll see a list of hardware components that you can query:
OperationVersion : OperationVersion
OSVersion : OSVersion
HistoryVersion : 0
Platform : Platform
System : System
Processor : Processor
Memory : Memory
Monitors : Monitors
Graphics : Graphics
Disk : Disk
CompletionStatus : CompletionStatus
AssessmentRunTime : AssessmentRunTime
For example, if you’d like to get exact information about the processor your machine is using, try this:
$xml.WinSAT.SystemConfig.Processor.Instance.Signature
The result is a detailed description:
Manufacturer : Manufacturer
Stepping : 5
Model : 14
Family : 6
ExtendedModel : 7
ExtendedFamily : 0
CompactSignature : 460517
Unfortunately, the XML files are a very nested structure. If you wanted to know the Manufacturer of your processor, you’d have to requery this property:
$xml.WinSAT.SystemConfig.Processor.Instance.Signature.Manufacturer
Invoking Hardware Assessment
You can use WinSAT.exe anytime you want to assess your hardware. When you run WinSAT.exe manually, you can specify a path to your own xml file, too.
Running all assessments can take a minute or two. Keep in mind that running WinSAT.exe requires Administrator privileges. Reading the produced xml files does not.
Running Fresh Formal Assessment
To run a fresh formal test (including all hardware subsystems) and save the result to a custom xml file path, run this (with Administrator privileges):
$Path = "$env:temp\myreport.xml"
winsat formal -xml $Path
$xml = [xml]::new()
$xml.Load($Path)
Querying WinSAT
WinSAT.exe can create a range of assessments that are not necessarily performance-oriented. You can also query hardware features and discover devices such as optical disks. For this, WinSAT.exe supports a range of report types.
New-WinSatAssessment
is a quick PowerShell function that helps you create assessments easily. The function takes care of most of the routine steps:
- It suggests the different types of available assessments and takes a path to a custom xml file
- It runs the requested assessment and shows a progress bar
- It returns a ready-to-use XML object that you can use to drill into the produced data
Running the assessment can take some time. You can prettify the tool by piping the output to a progress bar:
function New-WinSatAssessment
{
param
(
[string]
[ValidateSet('formal','dwm','cpu','mem','d3d','disk','media','mfmedia','features')]
$CommandLine = 'formal',
[string]
$Path = "$env:temp\winsat_temp.xml"
)
# test admin status
If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{ Write-Warning "Run this with Administrator privileges!"; return}
# use Regex to parse the real-time status messages emitted by winsat.exe
$patternTime = '\d{2}:\d{2}:\d{2}\.\d{2}'
$patternString = "^> (.*?)\s*('.*'){0,1}$"
# run the tool...
winsat $CommandLine -xml $Path | ForEach-Object {
# ignore feedback about the time tests took:
$isTime = $_ -match $patternTime
if (!$isTime)
{
# output the parsed text in a progress bar:
$IsParsed = $_ -match $patternString
$status = @{}
if ($IsParsed)
{
if ($matches[2])
{
$status['Status'] = $matches[2]
}
Write-Progress -Activity $matches[1] @status
}
}
}
# load the xml file into an xml object...
$xml = [xml]::new()
$xml.Load($Path)
# and return it:
$xml
}
Here is how you can use New-WinSatAssessment
to discover computer hardware (make sure you run it from an elevated console):
# do a hardware scan:
$result = New-WinSatAssessment -CommandLine features
# emit information about disks:
$result.WinSAT.SystemConfig.Disk.Disk
The result looks similar to this:
id : \\.\PhysicalDrive1
DiskNum : 1
Vendor : Vendor
Model : Model
Size : Size
WriteCacheEnabled : FALSE
id : \\.\PhysicalDrive2
DiskNum : 2
Vendor : Vendor
Model : Model
Size : Size
WriteCacheEnabled : FALSE
id : \\.\PhysicalDrive3
DiskNum : 3
Vendor : Vendor
Model : Model
Size : Size
WriteCacheEnabled : FALSE
Due to the nature of the produced XML files, any detailed information is stored in a nested property. For a full report, you’d have to query these properties separately. Or, you can use calculated properties:
$result.WinSAT.SystemConfig.Disk.Disk | Select-Object -Property Id, DiskNum, WriteCacheEnabled, @{N='Vendor';E={$_.Vendor.'#cdata-section'}}, @{N='Model';E={$_.Model.'#cdata-section'}},@{N='SizeGB';E={[Math]::Round([int64]($_.Size.'#text')/1GB,1)}}
Now the result shows all information in one view:
id DiskNum WriteCacheEnabled Vendor Model SizeGB -- ------- ----------------- ------ ----- ------ \\.\PhysicalDrive1 1 FALSE Samsung Flash Drive 119,5 \\.\PhysicalDrive2 2 FALSE USB Flash Disk 60 \\.\PhysicalDrive3 3 FALSE Samsung Flash Drive 239