The document provides an introduction to Windows Management Instrumentation (WMI) and how to use it with Perl. WMI is a set of standards created by DMTF to manage Windows systems. It consists of DMI, WBEM and CIM. The document discusses how WMI works, connecting to it from Perl using monikers or SWBEM Locator, executing WQL queries, and provides examples of practical uses like getting route information, adding/deleting routes, and refreshing performance counter data. Practical code samples are provided in both VBScript and Perl scripting language (PLS).
2. WMI?
• What Means It?
• Who Made It?
• What Makes It tick?
• Where Might I use it for?
3. Who Made It?
• Set of Standards created by DMTF
(Desktop Management Task Force Distributed Management Task Force)
4. What Means It?
• Set of Standards created by DMTF
(Desktop Management Task Force Distributed Management Task Force)
Consisting of:
DMI (Desktop Management Interface)
WBEM (Web-Based Entreprise Management)
CIM (Common Interface Model)
Bundled together known as Windows Meta Instrumentation.
5. What Makes It tick? (1)
Namespace(s)
Provider Provider
Class(es) Class(es) Class(es)
6. What Makes It tick? (2)
Namespace(s)
Provider Provider
Class(es) Class(es) Class(es)
WMI Layer
COM-API, SCRIPTING API
OS Layer
7. What Makes It tick? (3)
Namespace(s)
Provider Provider
Class(es) Class(es) Class(es)
WMI Layer
COM-API, SCRIPTING API
OS Layer
WMI Classes, Objects & Properties
COM-API, SCRIPTING-API, ...
OS Specific Binaries, Registry, WBEM MIF & MOF Files, ...
NT4 W2K W2K3 W2K8 XP Vista ...
8. Where Might I use it for?
A Quick & quot;Uniformquot;
Development Interface
Reporting Interface
Device Management Interface
9. Wow My…It even has a Wizard ;-)
quot;Scriptomaticquot;
• quot;A completely new version of the famous Scriptomatic, the utility that
writes WMI scripts for you.
(And, in the process, teaches you the fundamental concepts behind
writing WMI scripts for yourself.)
• Unlike its predecessor, Scriptomatic 2.0 isn’t limited to writing just
VBScript scripts; instead, Scriptomatic 2.0 can write scripts in Perl,
Python, or JScript as well.
• In addition, Scriptomatic 2.0 gives you a host of new output formats to
use when running scripts, including saving data as plain-text, as a
stand-alone Web page, or even as XML. Scriptomatic 2.0 handles arrays,
it converts dates to a more readable format, and it works with all the
WMI classes on your computer; on top of all that, it also writes scripts
that can be run against multiple machines.“*
*Quote Microsoft Download Center
Download: http://www.microsoft.com/downloads/details.aspx?FamilyID=09dfc342-648b-4119-
b7eb-783b0f7d1178&DisplayLang=en
10. Example Perl WMI Query
1. use strict;
2. use Win32::OLE('in');
3. use constant wbemFlagReturnImmediately => 0x10;
4. use constant wbemFlagForwardOnly => 0x20;
5. my @computers = (quot;.quot;);
6. foreach my $computer (@computers) {
7. my $objWMI = Win32::OLE->GetObject(quot;winmgmts:$computerrootCIMV2quot;)
or die quot;WMI connection failed.nquot;;
8. my $colItems = $objWMI->ExecQuery(quot;SELECT * FROM Win32_NetworkAdapterquot;, quot;WQLquot;,
9. wbemFlagReturnImmediately | wbemFlagForwardOnly);
10. foreach my $objItem (in $colItems) {
11. print (quot;TimeOfLastReset: quot;
12. .UTCDate($objItem->{TimeOfLastReset}).quot;nquot;);
13. print quot;TimeOfLastReset: $objItem->{TimeOfLastReset}nquot;;
14. print quot;nquot;;
15. }
16. }
17. sub UTCDate(){
18. my $WmiDate = qr/(d{4})(d{2})(d{2})(d{2})(d{2})
19. (d{2}).(d{6})([+-])(.*)$
20. /ox;
21. $_[0] =~ s/$WmiDate/$1 $2 $3 $4h $5m $6s (UTC$8$9m)/;
22. return $_[0];
23. }
24. #TimeOfLastReset: 20071027003940.826905+120
25. #TimeOfLastReset: 2007 10 27 00h 39m 40s (UTC+120m)
11. Connecting Perl to WMI (1)
• Moniker
1. use Win32::OLE('in');
2. use strict;
3. $strComputer = '.';
4. $objWMI = Win32::OLE->GetObject('winmgmts:' . $strComputer .
'rootcimv2');
Constructing a Moniker String: http://msdn2.microsoft.com/en-us/library/aa389292.aspx
12. Connecting Perl to WMI (2)
• SWBEM Locator
1. use Win32::OLE('in');
2. use strict;
3. my $objWMILocator = Win32::OLE->CreateObject(quot;WbemScripting.SWbemLocatorquot;);
4. $objWMILocator->Security_->{AuthenticationLevel} = 6;
5. my $objWMIComputer = $objWMILocator->ConnectServer($strComputer, quot;rootcimv2quot;,
$strLocalUser, $strLocalPasswd);
Connecting to WMI on a Remote Computer: http://msdn2.microsoft.com/en-us/library/aa389290.aspx
13. WQL (SQL for WMI)
AND NOT
ASSOCIATORS OF NULL
FALSE OR
FROM REFERENCES OF
GROUP Clause SELECT
HAVING TRUE
IS WHERE
ISA WITHIN
KEYSONLY __CLASS
LIKE
WQL (SQL for WMI): http://msdn2.microsoft.com/en-us/library/aa394606.aspx
14. WQL - ExecQuery
1. my $objWMI = Win32::OLE->GetObject(quot;winmgmts:$computerrootCIMV2quot;)
or die quot;WMI connection failed.nquot;;
2. my $colItems = $objWMI->ExecQuery(quot;SELECT * FROM Win32_NetworkAdapter“,
quot;WQLquot;, wbemFlagReturnImmediately | wbemFlagForwardOnly);
3. foreach my $objItem (in $colItems) {
4. print ( quot;TimeOfLastReset: quot;
5. . UTCDate($objItem->{TimeOfLastReset}).quot;nquot;);
6. print quot;TimeOfLastReset: $objItem->{TimeOfLastReset} nnquot;;
7. }
Calling a Method: http://msdn2.microsoft.com/en-us/library/aa384832.aspx
WbemFlagEnum: http://msdn2.microsoft.com/en-us/library/Aa393980.aspx
15. Example Perl WQL ‘Associators Of’
1. use win32::ole;
2. use strict;
3. my $objWMI = Win32::OLE->GetObject('winmgmts:.rootcimv2')
or die quot;WMI connection failed.nquot;;
4. my $colNAs = $objWMI->ExecQuery( 'select * ' . ' from Win32_NetworkAdapter' );
5. foreach my $objNA( in $colNAs) {
6. my $colSubNAConfig =
7. $objWMI->ExecQuery( 'ASSOCIATORS OF {Win32_NetworkAdapter.DeviceID=''
8. . $objNA->DeviceID . ''} '
9. . ' WHERE resultClass = '
10. . ' win32_NetworkAdapterConfiguration' );
11. foreach my $objNAConfig ( in $colSubNAConfig ) {
12. if ( $objNAConfig->DHCPEnabled == 1 ) {
13. my $intReturnCode = $objNAConfig->RenewDHCPLease();
14. if ( $intReturnCode == 0 ) {
15. print quot;Renewed IP Configuration for quot;.$objNA->Name ;
16. }
17. elsif ( $intReturnCode == 1 ) {
18. print quot;You must reboot to renew the IP Configuration for quot;
19. .$objNA->Name ;
20. }
21. }
22. }
23. }
16. WMI UTC Date/Time (1)
Based on the CIM datetime/interval format
Formatting: yyyymmddHHMMSS.mmmmmmsUUU or yyyy-mm-dd HH:MM:SS:mmm
1. foreach my $objItem (in $colItems) {
2. print (quot;TimeOfLastReset: quot;
.UTCDate($objItem->{TimeOfLastReset})
3.
4. .quot;nquot;);
5. print quot;TimeOfLastReset: $objItem->{TimeOfLastReset}nquot;;
6. print quot;nquot;;
7. }
8. }
9. #TimeOfLastReset: 20071027003940.826905+120
10. #TimeOfLastReset: 2007 10 27 00h 39m 40s (UTC+120m)
17. WMI UTC Date/Time (2)
Based on the CIM datetime/interval format
Formatting: yyyymmddHHMMSS.mmmmmmsUUU or yyyy-mm-dd HH:MM:SS:mmm
1. sub UTCDate(){
2. my $WMIDate = $_[0];
3. $WMIDate =~ s/[^0-9-+]//gis;
4. my $WmiDateRaw = qr/(d{4})(d{2})(d{2})
5. (d{2})(d{2})(d{2})
6. (d{6})([+-])(.*)$
7. /ox;
8. my $WmiDateFormatted = qr/(d{4})-?(d{2})-?(d{2})
9. (d{2})(d{2})(d{2})
10. (d{3})$
11. /ox;
12. if ($WMIDate =~ s/$WmiDateRaw/$1 $2 $3 $4h $5m $6s (UTC$8$9m)/){
13. return $WMIDate;
14. };
15. if ($WMIDate =~ s/$WmiDateFormatted/$1 $2 $3 $4h $5m $6s/){
16. return $WMIDate;
17. };
18. }
19. #TimeOfLastReset: 20071027003940.826905+120
20. #TimeOfLastReset: 2007 10 27 00h 39m 40s (UTC+120m)
18. WMI Practical: ‘Route Print’
1. use strict;
2. use Win32::OLE('in');
3. use constant wbemFlagReturnImmediately => 0x10;
4. use constant wbemFlagForwardOnly => 0x20;
5. my $objWMIService = Win32::OLE->GetObject(quot;winmgmts:localhostrootCIMV2quot;)
6. or die quot;WMI connection failed.nquot;;
7. my $colItems = $objWMIService->ExecQuery(quot;SELECT * FROM Win32_IP4RouteTablequot;,
quot;WQLquot;,
wbemFlagReturnImmediately | wbemFlagForwardOnly);
8. if (Win32::GetLastError()){
9. # Do Error Handling.
10. };
11. print quot;Destinationtquot;.quot;InterfaceIndextquot;.quot;Mask:tquot;.quot;Metric1:tquot;.
quot;Name:tquot;.quot;NextHop:tquot;.quot;Type:tquot;.quot;Protocol:nquot;;
12. print ‘-’ x 78;
13. foreach my $objItem ( in $colItems) {
14. print quot;$objItem->{Destination}tquot;;
15. print sprintf quot;0x%xquot;, $objItem->{InterfaceIndex}.quot;tquot;;
16. print quot;$objItem->{Mask}t“.quot;$objItem->{Metric1}tquot;;
17. print quot;$objItem->{Name}t“.quot;$objItem->{NextHop}tquot;;
18. print quot;$objItem->{Type}t“.print quot;$objItem->{Protocol}nquot;;
19. }
22. WMI Practical: ‘Refreshing’
• VBS (`cscript script.vbs`)
1. ' Get the performance counter instance for the System process
2. set Perf = GetObject(quot;winmgmts:Win32_PerfFormattedData_PerfOS_Processor.name=‘0'quot;)
3. ' Display some properties in a loop
4. for I = 1 to 5
5. Wscript.Echo quot;Perf PercentIdleTime = quot; & Perf.PercentIdleTime
6. Wscript.Sleep 2000
7. ' Refresh the objects
8. Perf.Refresh_
9. next
C:>cscript Demo_Refresher.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Perf PercentIdleTime = 100
Perf PercentIdleTime =
Perf PercentIdleTime = 100
Perf PercentIdleTime = 96
Perf PercentIdleTime = 96
C:>
23. WMI Practical: ‘Refreshing’
• PLS (`cscript script.pls`)
1. use Win32::OLE qw(in);
2. use strict;
3.
4. my $Perf = Win32::OLE->GetObject(
quot;winmgmts:Win32_PerfFormattedData_PerfOS_Processor.name=‘0'quot;);
5. for (my $i = 1;$i <= 5 ;$i++){
6. sleep 5;
7. $Perf->Refresh_();
8. print quot;PercentIdleTime: $Perf->{PercentIdleTime}nquot;;
9. }
C:>cscript Demo_Refresher.pls
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Perf PercentIdleTime = 100
Perf PercentIdleTime =
Perf PercentIdleTime = 96
Perf PercentIdleTime = 93
Perf PercentIdleTime = 97
C:>