Share via


Create custom Perfmon counters and update them from a CSV file using PowerShell

Adding Perfmon counters to a Visual Studio load test is useful to monitor remote host's metrics such a usage of Processor, Memory or Local Disks. You can add these metrics to a graph and overlay Load Test metrics such as throughput or response times for analysis.

When you have third party applications that need to be monitored, such as a program causing load on the 'system under test'. It can be useful to add these metrics to the VS Load test graphs in the form of custom Perfmon counters.

One of the easiest ways I have found so far of creating Perfmon counters is described on this article by Michael Repperger: article.

The program in question that is causing load to the system is also producing a CSV log, using Michael's sample and then using the import-csv cmdlet, we can consume the csv log and update Perfmon counters.

These the counters can be added to Counter Sets on Visual Studio and once a Load Test is running the new metrics would get collected and they can be used for analysis.

Below is a sample PowerShell script:


$categoryName = "UI Scripts"
$categoryHelp = "Transaction Response Times for UI Scripts"
$categoryType = [System.Diagnostics.PerformanceCounterCategoryType]::MultiInstance
 
$categoryExists = [System.Diagnostics.PerformanceCounterCategory]::Exists($categoryName)
 
 
If (-Not $categoryExists)
{
  $objCCDC = New-Object System.Diagnostics.CounterCreationDataCollection
 
  $objCCD1 = New-Object System.Diagnostics.CounterCreationData
  $objCCD1.CounterName = "Transaction Response Time"
  $objCCD1.CounterType = "NumberOfItems32"
  $objCCD1.CounterHelp = "Duration in Miliseconds of a UI transaction"
  $objCCDC.Add($objCCD1) | Out-Null
 
  [System.Diagnostics.PerformanceCounterCategory]::Create($categoryName, $categoryHelp, $categoryType, $objCCDC) | Out-Null
}
 
$perfInst1a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Transaction Response Time", "Transaction1", $false)
$perfInst2a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Transaction Response Time", "Transaction2", $false)
$perfInst3a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Transaction Response Time", "Transaction3", $false)
$perfInst4a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Transaction Response Time", "Transaction4", $false)
$perfInst5a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Transaction Response Time", "Transaction5", $false)
$perfInst6a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Transaction Response Time", "Transaction6", $false)
$perfInst7a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Transaction Response Time", "Transaction7", $false)

 

$checkIfSame1 = ""
for ($i = 1; $i -lt 100000; $i++){
    $timings = import-csv "C:\Users\edwinh\Desktop\test.csv"
    $checkIfSame2 = $timings[$timings.Length-1].'Transaction1,' -as[int]
    If($checkIfSame1 -ne $checkIfSame2){
        $perfInst1a.RawValue = $timings[$timings.Length-1].'Transaction1' -as[int]
        $perfInst2a.RawValue = $timings[$timings.Length-1].'Transaction2' -as[int]
        $perfInst3a.RawValue = $timings[$timings.Length-1].'Transaction3' -as[int]
        $perfInst4a.RawValue = $timings[$timings.Length-1].'Transaction4' -as[int]
        $perfInst5a.RawValue = $timings[$timings.Length-1].'Transaction5' -as[int]
        $perfInst6a.RawValue = $timings[$timings.Length-1].'Transaction6' -as[int]
        $perfInst7a.RawValue = $timings[$timings.Length-1].'Transaction7' -as[int]
    }
    $checkIfSame1 = $checkIfSame2
Start-Sleep -s 2
}
 
 
Read-Host