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.



use strict;
use warnings;

use Win32::OLE;


my $interval = 1;
my $key = 'Name';
my @properties = qw(PercentIdleTime PercentProcessorTime PercentPrivilegedTime PercentUserTime PercentInterruptTime TimeStamp_Sys100NS);

my $hash1 = {};

my $wmi = Win32::OLE->GetObject("winmgmts://./root/cimv2")
or die "Failed to get object\n";


my $list = $wmi->InstancesOf('Win32_PerfRawData_PerfOS_Processor')
or die "Failed to get instance object\n";

my $v;
foreach $v (in $list) {
map{$hash1->{$v->{$key}}->{$_} = $v->{$_} }@properties;
}

while(sleep 1){

$list = $wmi->InstancesOf('Win32_PerfRawData_PerfOS_Processor')
or die "Failed to get instance object\n";

my $hash = {};
foreach $v (in $list) {
map{$hash->{$v->{$key}}->{$_} = $v->{$_} }@properties;
}

my $cpu_time = sprintf("%.2f", (1 - get_value($hash1->{'_Total'}, $hash->{'_Total'}, 'PercentProcessorTime' )) * 100);
my $cpu_idle = sprintf("%.2f", 100-$cpu_time);
my $cpu_user = sprintf("%.2f", get_value($hash1->{'_Total'}, $hash->{'_Total'}, 'PercentUserTime' )* 100);
my $cpu_priv = sprintf("%.2f", get_value($hash1->{'_Total'}, $hash->{'_Total'}, 'PercentPrivilegedTime' )* 100);
my $cpu_int = sprintf("%.2f", get_value($hash1->{'_Total'}, $hash->{'_Total'}, 'PercentInterruptTime' )* 100);
printf "CPU Time %s %% , privileged %s %% , user %s %%, interrupt %s %%\n", $cpu_time,$cpu_priv,$cpu_user,$cpu_int;

$hash1 = $hash;
}


exit;

sub get_value {
my $h1 = shift;
my $h2 = shift;
my $property = shift;
return (($h2->{$property} - $h1->{$property})/($h2->{'TimeStamp_Sys100NS'}-$h1->{'TimeStamp_Sys100NS'}));
}




Output sample:


CPU Time 2.03 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 1.87 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 2.16 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 1.76 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 2.19 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 1.77 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 1.98 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 1.93 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 2.08 % , privileged 1.96 % , user 0.00 %, interrupt 0.00 %
CPU Time 2.84 % , privileged 2.94 % , user 0.00 %, interrupt 0.00 %