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

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

  • Comments 2
  • Likes

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 Property       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
----                                                           ------------       -----------
\\mred1\processor information(_total)\processor state flags    _total                       0
\\mred1\processor information(0,_total)\processor state flags  0,_total                     0
\\mred1\processor information(0,3)\processor state flags       0,3                          0
\\mred1\processor information(0,2)\processor state flags       0,2                          0
\\mred1\processor information(0,1)\processor state flags       0,1                          0
\\mred1\processor information(0,0)\processor state flags       0,0                          0
\\mred1\processor information(_total)\% of maximum frequency   _total                       0
\\mred1\processor information(0,_total)\% of maximum frequency 0,_total                     0
\\mred1\processor information(0,3)\% of maximum frequency      0,3                          0
\\mred1\processor information(0,2)\% of maximum frequency      0,2                          0
\\mred1\processor information(0,1)\% of maximum frequency      0,1                          0
\\mred1\processor 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
----                                                       ------------      -----------
\\mred1\processor information(_total)\c1 transitions/sec   _total        7180.4703476188
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total      7180.4703476188
\\mred1\processor information(0,3)\c1 transitions/sec      0,3          1922.74322394713
\\mred1\processor information(0,2)\c1 transitions/sec      0,2          2039.01604283622
\\mred1\processor information(0,1)\c1 transitions/sec      0,1          2147.80348711872
\\mred1\processor information(0,0)\c1 transitions/sec      0,0          1070.90759371672
\\mred1\processor information(_total)\dpcs queued/sec      _total       176.155815741847
\\mred1\processor information(0,_total)\dpcs queued/sec    0,_total     176.155815741847
\\mred1\processor information(_total)\interrupts/sec       _total       2074.94584094787
\\mred1\processor information(0,_total)\interrupts/sec     0,_total     2074.94584094787
\\mred1\processor information(0,3)\interrupts/sec          0,3          441.138076815277
\\mred1\processor information(0,2)\interrupts/sec          0,2          540.444046596091
\\mred1\processor information(0,1)\interrupts/sec          0,1          535.952821832135
\\mred1\processor 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 information, 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
----                                                       ------------      -----------
\\mred1\processor information(_total)\c1 transitions/sec   _total        7180.4703476188
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total      7180.4703476188
\\mred1\processor information(_total)\c1 transitions/sec   _total       7135.11877036386
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total     7135.11877036386
\\mred1\processor information(_total)\c1 transitions/sec   _total       7042.68233293539
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total     7042.68233293539
\\mred1\processor information(_total)\c1 transitions/sec   _total       7256.44182560112
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total     7256.44182560112
\\mred1\processor information(_total)\c1 transitions/sec   _total        7145.0786818399
\\mred1\processor 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
----                                                       ------------      -----------
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total     7042.68233293539
\\mred1\processor information(_total)\c1 transitions/sec   _total       7042.68233293539
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total     7135.11877036386
\\mred1\processor information(_total)\c1 transitions/sec   _total       7135.11877036386
\\mred1\processor information(_total)\c1 transitions/sec   _total        7145.0786818399
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total      7145.0786818399
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total      7180.4703476188
\\mred1\processor information(_total)\c1 transitions/sec   _total        7180.4703476188
\\mred1\processor information(0,_total)\c1 transitions/sec 0,_total     7256.44182560112
\\mred1\processor information(_total)\c1 transitions/sec   _total       7256.44182560112


PS C:\>

 

KB, that is all there is to collecting performance data and using Windows PowerShell 2.0 to process the data. If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Found all well in XP or Win7

    For Vista:

    The following worked ...

    (Get-Counter -ListSet 'processor').paths | Get-Counter -MaxSamples 3

    Unless I have something wrong,

    Hope this helps.

    A.

  • I am pulling counter samples for Web Service - Current Connections.

    How do I filter to show only the web sites that have connections?  For instance I don't want to see any values for sites with zero connections.

    Thanks,

    Hank