Wednesday, January 15, 2014

Powershell write-epa function for psEPA

 The psEPA is an extension of the Introscope .Net Agent that runs powershell scripts and collects the output as input to Introscope.  I wrote it because using the standard java based EPA wasn't always practical.  It was one of those necessity things I found I needed when building the latest iteration of the Citrix field pack.

So, I wanted an easy way to get metrics out of a cmdlet or pipe without having to go thru formatting.  And I really wanted it to be a function or pipeline section you could use generically.

Hence the write-epa function

This:  PS C:\Users\meaje04> get-process | write-epa -mname Name -mvalue CPU -longname TestMachine`|

Name – the object property name to use for the metric name
CPU – another object property name to use for the metric value
TestMachine`| - a literal value to prepend to the metric name

Gives this:  (formatted for epa)

TestMachine|AcroRd32:CPU=54
TestMachine|AcroRd32:CPU=0
TestMachine|ApMsgFwd:CPU=54
TestMachine|ApntEx:CPU=1
TestMachine|Apoint:CPU=5
TestMachine|armsvc:CPU=0
TestMachine|audiodg:CPU=4763
TestMachine|BcmDeviceAndTaskStatusService:CPU=2
TestMachine|cam:CPU=0
TestMachine|CdfSvc:CPU=0
TestMachine|communicator:CPU=135
TestMachine|conhost:CPU=0
TestMachine|conhost:CPU=0
TestMachine|conhost:CPU=0

And this:  PS C:\Users\meaje04> (Get-Counter "\\$env:computername\PhysicalDisk(*)\Current Disk Queue Length").Countersamples | write-epa -mname InstanceName -mvalue CookedValue -longname Disks`|

Gives this:
Disks|0 c::CookedValue=0
Disks|_total:CookedValue=0

The code:

 1 # take input object and write metric for psepa
 2 #   get-process | .\write-metric.ps1 -mname "processname" -mvalue "handles" -longname "Windows`|Processes`|" 
 3 #   Use any piped object as input, specify the metric name with -mname, specify the value with -mvalue,  specify a long name with -longname
 4 function write-epa {
 5 param( [string]$mname = "name", [string]$mvalue = "value",[string]$longName="Default`|") 
 6 begin { $x2 = 0; }
 7 process {
 8         foreach ($thing in $input) {     
 9                  $mn = $thing."$mname"
10                  $mv = $thing."$mvalue"
11                  $isNumber = [System.Int32]::TryParse($mv, [ref] ($x2))
12                 if ($isNumber) { [Int]$mvv = $mv } else { [string]$mvv = $mv }
13                 $smetric =  $longName + $mn + ":" +$mvalue.toString() + "=" + $mvv
14                 write-host $smetric 
15                 
16 
17         }
18  }