Use PowerShell to Create and Update Performance Counters

SCOM has a wonderful ability to take data from custom data sources, such as scripts, and treat them as performance counters with the System.Performance.DataGenericMapper module.  For more information please see https://msdn.microsoft.com/en-us/library/ee692961.aspx

However, sometimes you might need to create a "real" performance counter that people can see with PerfMon for real-time debugging.

Below is a simple PowerShell script that will create a Multi-Instance.

In this example I'm hard-coding in some values for the performance counters.  I'm going to assume that the reader is capable of authoring his or her own test code.

Important Notes:

  1. You must run PowerShell in an Administrator to create or edit performance counters
  2. The instances will go away when PowerShell exits.  These instances are only available while your script is running.  I stuck a Read-Host at the end to keep the script running in case you need time to get PerfMon open.

# If you need to delete the performance object and have it re-created call this:
# [System.Diagnostics.PerformanceCounterCategory]::Delete("<categoryNameGoesHere>")

$categoryName = "OffBox-HTTP"
$categoryHelp = "A Performance object for HTTP Synthetic Testing"
$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 = "Execution-Time-in-ms"
  $objCCD1.CounterType = "NumberOfItems32"
  $objCCD1.CounterHelp = "Number of ms executing the HTTP Synthetic"
  $objCCDC.Add($objCCD1) | Out-Null
 
  $objCCD2 = New-Object System.Diagnostics.CounterCreationData
  $objCCD2.CounterName = "Execution-Success"
  $objCCD2.CounterType = "NumberOfItems32"
  $objCCD2.CounterHelp = "100 means success. 0 means failure."
  $objCCDC.Add($objCCD2) | Out-Null
 
  [System.Diagnostics.PerformanceCounterCategory]::Create($categoryName, $categoryHelp, $categoryType, $objCCDC) | Out-Null
}

$perfInst1a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Execution-Time-in-ms", "www.xbox.com", $false)
$perfInst1b = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Execution-Success", "www.xbox.com", $false)
$perfInst2a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Execution-Time-in-ms", "www.microsoft.com", $false)
$perfInst2b = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Execution-Success", "www.microsoft.com", $false)

$perfInst1a.RawValue = 10
$perfInst1b.RawValue = 100
$perfInst2a.RawValue = 20
$perfInst2b.RawValue = 100
Start-Sleep 10
$perfInst1a.RawValue = 16
$perfInst1b.RawValue = 0
$perfInst2a.RawValue = 25
$perfInst2b.RawValue = 100
Start-Sleep 10
$perfInst1a.RawValue = 33
$perfInst1b.RawValue = 100
$perfInst2a.RawValue = 18
$perfInst2b.RawValue = 0
Start-Sleep 10
$perfInst1a.RawValue = 47
$perfInst1b.RawValue = 100
$perfInst2a.RawValue = 29
$perfInst2b.RawValue = 100
Read-Host

So, how does this work?

The Category Type comes from here https://msdn.microsoft.com/en-us/library/system.diagnostics.performancecountercategorytype(v=vs.110).aspx  There are really only two types.  MultiInstance, like Processor, and SingleInstance like Memory.

Counter Type comes from here https://msdn.microsoft.com/en-us/library/system.diagnostics.performancecountertype(v=vs.110).aspx I chose NumberOfItems32 because it is the most simple, basic type.  I'll leave the use of more complex types as an exercise for the reader.

This block

$perfInst1a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Execution-Time-in-ms", "www.xbox.com", $false)
$perfInst1b = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Execution-Success", "www.xbox.com", $false)
$perfInst2a = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Execution-Time-in-ms", "www.microsoft.com", $false)
$perfInst2b = New-Object System.Diagnostics.PerformanceCounter($categoryName, "Execution-Success", "www.microsoft.com", $false)

gets read-write instances of the counters.  The $false is for the readOnly parameter here https://msdn.microsoft.com/en-us/library/356cx381(v=vs.110).aspx

Obviously there is much, much, much more you can do with performance counters.  This was only intended to be the most simple of examples.

I'm also attaching the example script as a text file.

PerfCtr-ps1.txt