February 16th, 2010

Hey, Scripting Guy! With Windows PowerShell, How Can I Get the Same Information I Get Via PerfMon?

Bookmark and Share 

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! Your article on accessing performance counters was pretty cool, but it did not really tell me anything. For example, I am interested in getting the same kind of information in Windows PowerShell that I can get in Performance Monitor (PerfMon). Is this possible?

— KB

 

Hey, Scripting Guy! AnswerHello KB,

Microsoft Scripting Guy Ed Wilson here. I am still convalescing in Murrells Inlet, South Carolina. The Scripting Wife is an absolute genius sometimes, and this was definitely one of her better ideas. The beach, the sand, the cool ocean breeze, and the marshlands are all soothing to the mind. This morning, I am up early with my Thermos of tea, my camera, and my laptop as I head out into the marshlands that form an important part of the Murrells Inlet ecosystem. From my vantage point, I can see a long-legged bird as he stands on a float of sea grass. His reflection on the water adds an abstract quality to the picture I snapped.

Image of bird and its reflection

 

Using the Windows PowerShell 2.0 Get-Counter cmdlet, you can retrieve the paths to each of the processor information performance counters, and retrieve three samples of the data. The command to do this is shown here:

(Get-Counter -ListSet ‘processor information’).paths | Get-Counter -MaxSamples 3

The results of running the above command are shown in the following image.

Image of results of running command

If you wish to wait a certain interval between samples, you can specify the -SampleInterval in seconds:

(Get-Counter -ListSet ‘processor information’).paths | Get-Counter -MaxSamples 5 -SampleInterval 2

Of course, displaying performance counter data on the Windows PowerShell console every two seconds is not much better than watching the performance monitor line scroll across the screen in PerfMon. To really begin to perform any kind of analysis of the data, you need to store the data. The easiest way to do this is to simply store the results in a variable. This is shown here:

$a = (Get-Counter -ListSet ‘processor information’).paths | Get-Counter -MaxSamples 5 -SampleInterval 2

As seen in the following image, the $a variable contains all of the performance counter information that was previously scrolling across the screen.

Image of $a variable containing all performance counter information

 

If we use the Get-Member cmdlet (gm is the alias for the Get-Member cmdlet), we can see that the $a variable contains a PerformanceCounterSampleSet object. The members of the PerformanceCounterSampleSet object are seen here:

PS C:> $a | gm

   TypeName: Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet

Name           MemberType     Definition
—-           ———-     ———-
Equals         Method         bool Equals(System.Object obj)
GetHashCode    Method         int GetHashCode()
GetType        Method         type GetType()
ToString       Method         string ToString()
CounterSamples Prope rty       Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSample[] CounterSamples {ge…
Timestamp      Property       System.DateTime Timestamp {get;set;}
Readings       ScriptProperty System.Object Readings {get=$strPaths = “”…

PS C:>

Because the PerformanceCounterSampleSet object is a collection, it is possible to index directly into a single instance of the readings. To do this, use the same technique you would use with an array, as shown in the following image.

Image of indexing directly into single instance of readings

 

The countersamples property returns an instance of the PerformanceCounterSample object, as shown here:

PS C:> $a[0].countersamples | gm

   TypeName: Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSample

Name             MemberType Definition
—-             ———- ———-
Equals           Method     bool Equals(System.Object obj)
GetHashCode      Method     int GetHashCode()
GetType          Method     type GetType()
ToString         Method     string ToString()
CookedValue      Property   System.Double CookedValue {get;set;}
CounterType      Property   System.Diagnostics.PerformanceCounterType CounterType {get;set;}
DefaultScale     Property   System.UInt32 DefaultScale {get;set;}
InstanceName     Property   System.String InstanceName {get;set;}
MultipleCount    Property   System.UInt32 MultipleCount {get;set;}
Path             Property   System.String Path {get;set;}
RawValue         Property   System.UInt64 RawValue {get;set;}
SecondValue      Property   System.UInt64 SecondValue {get;set;}
Status           Property   System.UInt32 Status {get;set;}
TimeBase         Property   System.UInt64 TimeBase {get;set;}
Timestamp        Property   System.DateTime Timestamp {get;set;}
Timestamp100NSec Property   System.UInt64 Timestamp100NSec {get;set;}

PS C:>

The more interesting properties are the path to the counter, the instance name, and the CookedValue. A table displaying this truncated information is shown here (ft is an alias for the Format-Table cmdlet, and wildcards characters are used to reduce the typing requirements for the property names):

PS C:> $a[0].countersamples | ft *path, *instance*, *cook* -AutoSize

Path                                                           InstanceName       CookedValue
—-                                                           ————       ———–
\mred1processor information(_total)processor state flags    _total                       0
\mred1processor information(0,_total)processor state flags  0,_total                     0
\mred1processor information(0,3)processor state flags       0,3                          0
\mred1processor information(0,2)processor state flags       0,2                          0
\mred1processor information(0,1)processor state flags       0,1                          0
\mred1processor information(0,0)processor state flags       0,0                          0
\mred1processor information(_total)% of maximum frequency   _total                       0
\mred1processor information(0,_total)% of maximum frequency 0,_total                     0
\mred1processor information(0,3)% of maximum frequency      0,3                          0
\mred1processor information(0,2)% of maximum frequency      0,2                          0
\mred1processor information(0,1)% of maximum frequency      0,1                          0
\mred1processor information(0,0)% of maximum frequency      0,0                          0

You can also use the Where-Object cmdlet to filter out counter samples before displaying them in the table. The question mark (?) is an alias for the Where-Object cmdlet and ft is an alias for the Format-Table cmdlet:

PS C:> $a[0].countersamples | ? { $_.cookedvalue -gt 100 } | ft -AutoSize

Path                                                       InstanceName      CookedValue
—-                                                       ————      ———–
\mred1processor information(_total)c1 transitions/sec   _total        7180.4703476188
\mred1processor information(0,_total)c1 transitions/sec 0,_total      7180.4703476188
\mred1processor information(0,3)c1 transitions/sec      0,3          1922.74322394713
\mred1processor information(0,2)c1 transitions/sec      0,2          2039.01604283622
\mred1processor information(0,1)c1 transitions/sec      0,1          2147.80348711872
\mred1processor information(0,0)c1 transitions/sec      0,0          1070.90759371672
\mred1processor information(_total)dpcs queued/sec      _total       176.155815741847
\mred1processor information(0,_total)dpcs queued/sec    0,_total     176.155815741847
\mred1processor information(_total)interrupts/sec       _total       2074.94584094787
\mred1processor information(0,_total)interrupts/sec     0,_total     2074.94584094787
\mred1processor information(0,3)interrupts/sec          0,3          441.138076815277
\mred1processor information(0,2)interrupts/sec          0,2          540.444046596091
\mred1processor information(0,1)interrupts/sec          0,1          535.952821832135
\mred1processor information(0,0)interrupts/sec          0,0          557.410895704371

PS C:>

Because the $a variable contains a collection of performance data, you might be interested in walking through the collection of sample data, and then looking for a cookedvalue that is greater than 3000. When you obtain the inf ormation, you might like to stick with the table output. The percentage sign (%) is an alias for the ForEach-Object Windows PowerShell cmdlet. The question mark (?) is an alias for the Where-Object cmdlet. The –gt is the operator that means greater than and the $_ character is the symbol that refers to the current object on the pipeline. And ft is an alias for the Format-Table cmdlet. The complete one-line command is shown here along with the complete data that was retrieved from my computer:

PS C:> $a | % { $_.countersamples | ? {$_.cookedvalue -gt 3000} } | ft -auto

Path                                                       InstanceName      CookedValue
—-                                                       ————      ———–
\mred1processor information(_total)c1 transitions/sec   _total        7180.4703476188
\mred1processor information(0,_total)c1 transitions/sec 0,_total      7180.4703476188
\mred1processor information(_total)c1 transitions/sec   _total       7135.11877036386
\mred1processor information(0,_total)c1 transitions/sec 0,_total     7135.11877036386
\mred1processor information(_total)c1 transitions/sec   _total       7042.68233293539
\mred1processor information(0,_total)c1 transitions/sec 0,_total     7042.68233293539
\mred1processor information(_total)c1 transitions/sec   _total       7256.44182560112
\mred1processor information(0,_total)c1 transitions/sec 0,_total     7256.44182560112
\mred1processor information(_total)c1 transitions/sec   _total        7145.0786818399
\mred1processor information(0,_total)c1 transitions/sec 0,_total      7145.0786818399

PS C:>

Because we are using standard Windows PowerShell cmdlets to process the performance information, we can also use the Sort-Object cmdlet to sort the data for us into a more readable output. The revised command that produces sorted information is shown here (note that sort is an alias for the Sort-Object cmdlet):

PS C:> $a | % { $_.countersamples | ? {$_.cookedvalue -gt 3000} } | sort cookedvalue | ft -auto

Path                                                       InstanceName      CookedValue
—-                                                       ————      ———–
\mred1processor information(0,_total)c1 transitions/sec 0,_total     7042.68233293539
\mred1processor information(_total)c1 transitions/sec   _total       7042.68233293539
\mred1processor information(0,_total)c1 transitions/sec 0,_total     7135.11877036386
\mred1processor information(_total)c1 transitions/sec   _total       7135.11877036386
\mred1processor information(_total)c1 transitions/sec   _total        7145.0786818399
\mred1processor information(0,_total)c1 transitions/sec 0,_total      7145.0786818399
\mred1processor information(0,_total)c1 transitions/sec 0,_total      7180.4703476188
\mred1processor information(_total)c1 transitions/sec   _total

Author

0 comments

Discussion are closed.