Thursday, March 10, 2011

How to collect CPU values from WMI. #perl #win32 #wmi

This program will demonstrate how easy it is to obtain data from Windows Management Instrumentation (WMI), using a perl script. By analogy other information may be collected from WMI.

To obtain these data, I used the WMI Performance Counter class "Win32_PerfRawData_PerfOS_Processor" , which provides me the counters that measure aspects of processor(s) activity.

Since the data collected via WMI are percentages. I just needed to calculate the percentage of time used for each counter, depending on the time interval between measurements.

  1. use strict;  
  2. use warnings;  
  3.   
  4. use Win32::OLE;  
  5.   
  6.   
  7. my $interval = 1;  
  8. my $key = 'Name';  
  9. my @properties = qw(PercentIdleTime PercentProcessorTime PercentPrivilegedTime PercentUserTime PercentInterruptTime TimeStamp_Sys100NS);  
  10.   
  11. my $hash1 = {};  
  12.   
  13. my $wmi = Win32::OLE->GetObject("winmgmts://./root/cimv2")  
  14.  or die "Failed to get object\n";  
  15.   
  16.   
  17. my $list = $wmi->InstancesOf('Win32_PerfRawData_PerfOS_Processor')  
  18.  or die "Failed to get instance object\n";  
  19.   
  20. my $v;   
  21. foreach $v (in $list) {     
  22.   map{$hash1->{$v->{$key}}->{$_}  = $v->{$_} }@properties;  
  23. }  
  24.    
  25. while(sleep 1){  
  26.   
  27.  $list = $wmi->InstancesOf('Win32_PerfRawData_PerfOS_Processor')  
  28.   or die "Failed to get instance object\n";  
  29.    
  30.  my $hash = {};  
  31.  foreach $v (in $list) {     
  32.   map{$hash->{$v->{$key}}->{$_}  = $v->{$_} }@properties;  
  33.  }  
  34.   
  35.  my $cpu_time = sprintf("%.2f", (1 - get_value($hash1->{'_Total'}, $hash->{'_Total'}, 'PercentProcessorTime' )) * 100);  
  36.  my $cpu_idle = sprintf("%.2f", 100-$cpu_time);  
  37.  my $cpu_user = sprintf("%.2f", get_value($hash1->{'_Total'}, $hash->{'_Total'}, 'PercentUserTime' )* 100);  
  38.  my $cpu_priv = sprintf("%.2f", get_value($hash1->{'_Total'}, $hash->{'_Total'}, 'PercentPrivilegedTime' )* 100);  
  39.  my $cpu_int = sprintf("%.2f", get_value($hash1->{'_Total'}, $hash->{'_Total'}, 'PercentInterruptTime' )* 100);    
  40.  printf "CPU Time %s %% , privileged %s %% , user %s %%, interrupt %s %%\n"$cpu_time,$cpu_priv,$cpu_user,$cpu_int;  
  41.   
  42.  $hash1 = $hash;  
  43. }  
  44.   
  45.   
  46. exit;  
  47.   
  48. sub get_value {  
  49.  my $h1 = shift;  
  50.  my $h2 = shift;  
  51.  my $property = shift;  
  52.  return (($h2->{$property} - $h1->{$property})/($h2->{'TimeStamp_Sys100NS'}-$h1->{'TimeStamp_Sys100NS'}));  
  53. }  



Output sample:

  1. CPU Time 2.03 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  2. CPU Time 1.87 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  3. CPU Time 2.16 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  4. CPU Time 1.76 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  5. CPU Time 2.19 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  6. CPU Time 1.77 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  7. CPU Time 1.98 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  8. CPU Time 1.93 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  9. CPU Time 2.08 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %  
  10. CPU Time 2.84 % , privileged 2.94 % , user 0.00 %, interrupt 0.00 %