Pulling Performance Counters from WMI with PowerShell

Recently I had a colleague that was asking me how they could pull performance counters manually.  Some of the options are using PerfMon or using WMI.

They had opted for going the WMI Route.. I thought this was something that may be useful so wanted to blog about it.

First, to get the perf classes from WMI we can query WMI for the list of classes. If you run the following snippit in PowerShell you will get a list of the classes that are out there.

 $name = "Win32_perfformatteddata" 
$WMIClasses = Get-WmiObject -List | Where-Object {$_.name -Match $name}

foreach($class in $WMIClasses)
{
$class.Name
}

image

We were dealing with Logical Disk counters so I will be using the Win32_perfformatteddata_perfdisk_LogicalDisk class.

So now we need to see what counters we have available for the class we chose, to do that we just run the following PowerShell line to get the details

 $disks = Get-WmiObject -Query "Select * from Win32_perfformatteddata_perfdisk_LogicalDisk"

The results will look like the screenshot below, you will get an instance for each disk, the screenshot below shows just one example.  As you can see we have many properties. Inside the red circle you can see AvgDiskBytesPerRead, AvgDiskBytesPerTransfer, etc…

image

For our example we wanted to see Disk Reads / Sec, Disk Writes / Sec and Current Disk Queue Length, so we wrote the below script to quickly pull this data, in 5 second increments for 1 minute and writes them to a csv file.  Of course this can be expanded and re-written to be more flexible but for a quick pull of performance counters it is an easy way to get results.

 $timeout = new-timespan -Minutes 1
$sw = [diagnostics.stopwatch]::StartNew()
$path = "c:\temp\counters.csv"

while ($sw.elapsed -lt $timeout)
{
$disks = Get-WmiObject -Query "Select * from Win32_perfformatteddata_perfdisk_LogicalDisk"
"Disk Name,Date,Disk Reads per Second, Disk Writes per Second, Current Disk Queue Length" >> $path
foreach($disk in $disks)
    { 
    $date = Get-Date -format s
    $disk.Name + "," + $date + "," + $disk.DiskReadsPerSec + "," + $disk.DiskWritesPerSec + "," + $disk.CurrentDiskQueueLength >> $path

    }
start-sleep -seconds 5
}
  

Then finally we get output like below (since we exported from PowerShell as text you may have to use Text to Columns in excel with the “,” as a delimiter to get the format below.

image

And then with a little work with a Pivot Table and Pivot Chart you can create a dynamic report based on the findings.

image

Comments

  • Anonymous
    October 13, 2015
    This instruction

    $disks = Get-WmiObject -Query "Select * from Win32_perfformatteddata_perfdisk_LogicalDisk"
    "Disk Name,Date,Disk Reads per Second, Disk Writes per Second, Current Disk Queue Length" >> $path

    i think it produces a file with headers but nothing more.
    I don't know in which momment $disk information goes to the file.

    Please can you put the entire script?
    Thanks
  • Anonymous
    October 21, 2015
    Try this: Get-WmiObject -Class Win32_perfformatteddata_perfdisk_LogicalDisk |Select-Object Name,DiskReadsPersec,DiskWritesPersec,CurrentDiskQueueLength| Export-Csv -NoTypeInformation -Path $path
  • Anonymous
    April 19, 2016
    Looks like there's a typo. Should match be $name not $Type:

    $name = "Win32_perfformatteddata"
    $WMIClasses = Get-WmiObject -List | Where-Object {$_.name -Match $name}
  • Anonymous
    April 19, 2016
    Jeremy thanks for the catch, fixed it.