WMI Scripting Primer: Part 1
中文版
Greg Stemp, Dean Tsaltas, and Bob Wells
Microsoft Corporation
Ethan Wilansky
Network Design Group
June 13, 2002
Summary: The Scripting Guys' first Scripting Clinic column shows how to use the WMI scripting library to create an array of useful Windows system administration scripts. (15 printed pages)
Microsoft® Windows® Management Instrumentation (WMI) is Microsoft's best-kept secret, or so we've been told. Be that as it may, make no mistake; WMI is Microsoft's primary management enabling technology for Windows. What does that mean to you? Well, if you manage Windows servers and workstations, or if you create Windows management applications, you need to know WMI. This article is the first in a series of articles that will teach you WMI, and more specifically, how to use the WMI scripting library to create a vast array of Windows system administration scripts.
Before we get started, we should take a second to thank Andrew Clinick for giving us the opportunity to carry Scripting Clinic forward. You could say Andrew wasn't kidding when he said he planned to delegate more in his last column! The fact is, Andrew is moving on to another project, so he graciously asked us to pick up where he left off. Despite our initial reluctance due to the high quality bar Andrew set for Scripting Clinic, we're glad to be here.
So who are we? We're the Scripting Guys; the team writing the System Administration Scripting Guide, a new book that will ship as part of the Microsoft® Windows Server 2003 Resource Kit. That's Dean on the left and Greg on the right in the column's mug shot. Rumor has it Ethan and Bob missed the photo op due to their weekly Botox appointment. So if their photos appear overly handsome when they do show up, we're here to tell you Ethan and Bob are really two of the nerdiest looking guys we've ever seen! Consider yourself warned.
What Is WMI?
Originally released in 1998 as an add-on component with Windows NT 4.0 Service Pack 4, WMI is the core management-enabling technology built into Windows 2000, Windows XP, and the Windows Server 2003 family of operating systems. Based on industry standards overseen by the Distributed Management Task Force (DMTF), WMI is the instrumentation and plumbing through which all—well, almost all—Windows resources can be accessed, configured, managed, and monitored.
To grasp the power and breadth of WMI, consider how you managed and monitored Windows workstations and servers yesteryear, and perhaps even today. You probably used, or use, numerous graphical administrative tools to manage Windows resources, such as disks, event logs, files, folders, file systems, networking components, operating system settings, performance data, printers, processes, registry settings, security, services, shares, users, groups, and so on.
Although the graphical tools provided a functional management solution, what did they all have in common? One answer is, prior to WMI, all Windows graphical administrative tools relied on Win32 application programming interfaces (APIs) to access and manage Windows resources. Why? Because the only way you could programmatically access Windows resources before WMI was through the Win32 APIs. This situation left Windows system administrators without an easy way to automate common system administrative tasks using popular scripting languages, because most scripting languages cannot call Win32 APIs directly. WMI changes that by providing a consistent model and framework through which all Windows resources are described and exposed to the outside world. And best of all, system administrators can use the WMI Scripting Library to create system administrative scripts to manage any Windows resource exposed through WMI!
Using Windows Script Host and Microsoft Visual Basic® Scripting Edition (VBScript), or any scripting language supporting COM automation (for example, ActiveState Corporation's ActivePerl), you can write scripts to manage and automate the following aspects of your enterprise systems, applications, and networks:
Quick Start to WMI Scripting
To give you some idea of what WMI scripting is all about, let's look at the seemingly trivial task of retrieving the total amount of physical memory installed in a remote Windows-based computer. Before WMI, this task could not be easily accomplished using a script without the addition of a third-party tool. In fact, prior to WMI, the only way to determine the amount of memory installed in a computer using a tool included with the operating system tool was by way of the System Properties dialog. Today, providing WMI is installed on the target computer and you have administrator access to the computer, you can retrieve the amount of physical memory installed in a remote Windows computer using a WMI script as simple as the script shown in Listing 1.
Listing 1. Retrieving total physical memory using WMI and VBScript
strComputer = "atl-dc-01"
Set wbemServices = GetObject("winmgmts:\\" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")
For Each wbemObject In wbemObjectSet
WScript.Echo "Total Physical Memory (kb): " & wbemObject.TotalPhysicalMemory
Next
To run the example script in Listing 1, copy and paste it into your favorite text editor (notepad.exe works too), change the value assigned to the strComputer variable to a valid WMI-enabled computer in your domain, save the script with a .vbs extension, and run the script as shown in Figure 1.
Figure 1. GetMemory.vbs output
With a little magic, and barring any typos, you should see the target computer's amount of physical memory echoed to the console.
Now, before you say, "Gee whiz, does it really take six lines of script to fetch the amount of memory in a computer?" let us politely chime in, because what's not yet obvious is that you can use the same basic steps as those demonstrated in Listing 1, to retrieve configuration and status information from any Windows resource exposed through WMI.
Suppose you want to retrieve the name, state, and startup type for all of the services installed on a remote computer. The example script in Listing 2 does exactly that using the same basic steps used in Listing 1.
Listing 2. Retrieving services information using WMI and VBScript
strComputer = "atl-dc-01"
Set wbemServices = GetObject("winmgmts:\\" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("Win32_Service")
For Each wbemObject In wbemObjectSet
WScript.Echo "Display Name: " & wbemObject.DisplayName & vbCrLf & _
" State: " & wbemObject.State & vbCrLf & _
" Start Mode: " & wbemObject.StartMode
Next
Running Listing 2 produces the output shown in Figure 2.
Figure 2. GetServices.vbs output
Suppose you're not interested in services, but you need to retrieve records from the Windows event logs. Again, using the script template in Listing 1, you can easily read the Windows event logs as demonstrated in Listing 3. Before you run Listing 3, we should point out that the example script can take a long time to run if your event logs contain thousands of records.
Listing 3. Reading Windows event log records
strComputer = "atl-dc-01"
Set wbemServices = GetObject("winmgmts:\\" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("Win32_NTLogEvent")
For Each wbemObject In wbemObjectSet
WScript.Echo "Log File: " & wbemObject.LogFile & vbCrLf & _
"Record Number: " & wbemObject.RecordNumber & vbCrLf & _
"Type: " & wbemObject.Type & vbCrLf & _
"Time Generated: " & wbemObject.TimeGenerated & vbCrLf & _
"Source: " & wbemObject.SourceName & vbCrLf & _
"Category: " & wbemObject.Category & vbCrLf & _
"Category String: " & wbemObject.CategoryString & vbCrLf & _
"Event: " & wbemObject.EventCode & vbCrLf & _
"User: " & wbemObject.User & vbCrLf & _
"Computer: " & wbemObject.ComputerName & vbCrLf & _
"Message: " & wbemObject.Message & vbCrLf
Next
If we examine Listings 1, 2, and 3 closely, we can make two very important observations about the three scripts. The first observation is that all three scripts perform the same three steps: the scripts connect to WMI, retrieve a WMI managed resource, and echo a few of the resource's properties. The second important observation is that the only thing changed in each script is the class name (that is, Win32_LogicalMemoryConfiguration, Win32_Service, and Win32_NTLogEvent respectively) identifying the target resource, and the resource's corresponding properties.
The three steps used in the scripts are common to any WMI script used to retrieve information about a WMI managed resource. Let's look at each step in a little more detail.
Step One: Connecting to the WMI Service
The first step in any WMI script is establishing a connection to the Windows Management Service on the target computer. Connecting to WMI on a local or remote computer is as simple as calling VBScript's Getobject function and passing GetObject the name of the WMI Scripting Library's moniker, which is "winmgmts:" followed by the name of the target computer.
Connecting to WMI in this way returns a reference to a SWbemServices object, which we reference using the variable named wbemServices in Listings 1, 2, and 3. SWbemServices is one of the dozen or so objects defined in the WMI scripting library. The WMI scripting library provides the set of general purpose objects scripts use to access the WMI infrastructure. Once you have a reference to a SWbemServices object, you can call any of the methods provided SWbemServices; InstancesOf is one such method.
Step Two: Retrieve Instances of WMI managed Resources
Admittedly, the second step largely depends on the task you want to perform. In the case of retrieving information about a WMI managed resource, step two is as simple as calling the SWbemServices object's InstancesOf method. As the methods name suggests, InstancesOf returns all the instances of the managed resource identified by the resource's class name. InstancesOf returns the requested resources in the form of a SWbemObjectSet collection, which we reference in Listings 1, 2, and 3 by using the variable named wbemObjectSet. SWbemObjectSet is another scripting object defined in the WMI scripting library.
Step Three: Display Properties of WMI managed Resources
The last and final step is enumerating the contents of the SWbemObjectSet collection. Each item in a SWbemObjectSet is a SWbemObject (yet another object in the WMI scripting library) that represents a single instance of the requested resource. You use SWbemObject to access the methods and properties defined in the managed resource's class definition.
So, if the scripting steps to retrieve information from WMI are identical, what are the Win32_LogicalMemoryConfiguration, Win32_Service, and Win32_NTLogEvent classes? Furthermore, where do they come from, what other classes are available, and how do you use them? The answers to these questions lie in the components that make up the WMI architecture. Let's have a look.
WMI Architecture
The WMI architecture consists of three primary layers as shown in Figure 3:
Figure 3. WMI architecture
We'll start at the lowest layer since that's where the resources reside.
Managed Resources
A managed resource is any logical or physical component, which is exposed and manageable by using WMI. Windows resources that can be managed using WMI include the computer system, disks, peripheral devices, event logs, files, folders, file systems, networking components, operating system subsystems, performance counters, printers, processes, registry settings, security, services, shares, SAM users and groups, Active Directory, Windows Installer, Windows Driver Model (WDM) device drivers, and SNMP Management Information Base (MIB) data to name a few. A WMI managed resource communicates with WMI through a provider. As you begin to write scripts to interact with WMI managed resources, you'll often see the term instance used to refer to a virtual representation of the managed resource in the running script.
WMI Infrastructure
The middle layer is the WMI infrastructure. WMI consists of three primary components: the Common Information Model Object Manager (CIMOM), the Common Information Model (CIM) repository, and providers. Together, the three WMI components provide the infrastructure through which configuration and management data is defined, exposed, accessed, and retrieved. A fourth component, albeit small, but absolutely essential to scripting is the WMI scripting library.
WMI Providers
WMI providers act as an intermediary between WMI and a managed resource. Providers request information from, and send instructions to WMI managed resources on behalf of consumer applications and scripts. For example, Listings 1 and 2 use the built-in Win32 provider to retrieve memory and service-related information. Listing 3 uses the built-in Event Log provider to retrieve records from the Windows event logs.
Providers hide the implementation details unique to a managed resource by exposing the managed resource to the WMI infrastructure based on WMI's standards-based, uniform access model. WMI providers communicate with their respective managed resources using the managed resources native APIs, and communicate with the CIMOM using WMI programming interfaces. For example, the built-in Event Log provider calls Win32 Event Log APIs to access event logs.
Software developers can develop and integrate add-on providers to expose the management functions unique to their products, based on WMI's extensible architecture. The Exchange Server 2000 provider, which monitors Exchange connector status is one such example. Likewise, Application Center, Operations Manager, Systems Management Server, Internet Information Server, and SQL Server all include WMI providers.
Providers are generally implemented as dynamic link libraries (DLLs) residing in the %SystemRoot%\system32\wbem directory. WMI includes many built-in providers for Windows 2000, Windows XP, and the Windows Server 2003 family of operating systems. The built-in providers, also known as standard providers, supply data and management functions from well-known operating system sources such as the Win32 subsystem, event logs, performance counters, and registry. Table 1 lists several of the standard WMI providers included with Windows 2000, Windows XP, and the Windows Server 2003 family of operating systems.
Table 1. Partial list of standard WMI providers
Provider DLL Namespace Description
Active Directory provider
dsprov.dll
root\directory\ldap
Maps Active Directory objects to WMI.
Event Log provider
ntevt.dll
root\cimv2
Manage Windows event logs, for example, read, backup, clear, copy, delete, monitor, rename, compress, uncompress, and change event log settings.
Performance Counter provider
wbemperf.dll
root\cimv2
Provides access to raw performance data.
Registry provider
stdprov.dll
root\default
Read, write, enumerate, monitor, create, and delete registry keys and values.
SNMP provider
snmpincl.dll
root\snmp
Provides access to SNMP MIB data and traps from SNMP-managed devices.
WDM provider
wmiprov.dll
root\wmi
Provides access to information on WDM device drivers.
Win32 provider
cimwin32.dll
root\cimv2
Provides information about the computer, disks, peripheral devices, files, folders, file systems, networking components, operating system, printers, processes, security, services, shares, SAM users and groups, and more.
Windows Installer provider
msiprov.dll
root\cimv2
Provides access to information about installed software.
Windows XP and Windows Server 2003 include many additional standard providers. For a complete list of standard providers, see the WMI Providers reference in the WMI Software Developers Kit (SDK) Documentation.
CIMOM
The CIMOM (pronounced see-mom) handles the interaction between consumers and providers. The term comes from the Web-Based Enterprise Management initiative and Common Information Model specification maintained by the Distributed Management Task Force.
You can think of the CIMOM as the WMI information broker. All WMI requests and data flow through the CIMOM. The Windows Management Instrumentation service, winmgmt.exe, provides the role of the CIMOM on Windows XP and the Windows Server 2003 family of operating systems, which runs under the control of the generic services host process, svchost.exe.
Note On computers running Windows 2000 or Windows NT 4.0 Service Pack 4, the WMI service runs as a separate service process. On computers running Windows Millennium Edition (Me), Windows 98, or Windows 95 OSR 2.5, WMI runs as a standard executable process.
In addition to providing the common interface through which consumers access WMI, the CIMOM provides the following core services to the WMI infrastructure:
Management applications, administrative tools, and scripts call into the CIMOM to mine data, subscribe to events, or to perform some other management-related task. The CIMOM obtains provider and class information necessary to service consumers' requests from the CIM. The CIMOM uses the information obtained from the CIM to hand-off consumer's requests to the appropriate provider.
CIM Repository(贮藏库)
WMI is based on the idea that configuration and management information from different sources can be uniformly(一致的) represented with a schema. The CIM is the schema, also called the object repository or class store that models the managed environment and defines every piece of data exposed by WMI. The schema is based on the DMTF Common Information Model standard.
Much like Active Directory's schema is built on the concept of a class, the CIM consists of classes. A class is a blueprint for a WMI manageable resource. However, unlike Active Directory classes, which represent objects created and stored in the directory, CIM classes generally represent dynamic resources. That is, instances of resources are not stored in the CIM, but are dynamically retrieved by a provider based on a consumer request. The reason for this is simple; the operational state for most WMI managed resources changes frequently and therefore must be read on-demand to ensure the most up-to-date information is retrieved.
Note The term repository is somewhat misleading in the context of the CIM. Although the CIM is a repository and is capable of storing static data, its primary role is storing the blueprints for managed resources.
Also like Active Directory classes, CIM classes are organized hierarchically where child classes inherit from parent classes. The DMTF maintains the set of core and common base classes from which system and application software developers, such as those at Microsoft, derive and create system- or application-specific extension classes.
Classes are grouped into namespaces, which are logical groups of classes representing a specific area of management. For example, the root\cimv2 namespace includes most of the classes that represent resources commonly associated with a computer and operating system. The classes used in the previous scripts (Win32_LogicalMemoryConfiguration, Win32_Service, and Win32_NTLogEvent) reside in the root\cimv2 namespace, and are just three of literally hundreds of classes defined in the CIM.
CIM classes consist of properties and methods. Properties describe the configuration and state of a WMI managed resource, and methods are executable functions that perform actions on the WMI managed resource.
(CIM类由属性和方法组成,属性描述了WMI托管资源的配置和状态,方法是可以在WMI托管资源上执行的函数)
Note Don't confuse the methods and properties defined by a CIM class with the methods and properties provided by automation objects in the WMI scripting library.
(注意,不要混淆了CIM类中和WMI脚本库中Automation对象的方法和属性)
Physically, the CIM resides in the %SystemRoot%\system32\wbem\Repository\FS\ directory and consists of the following four files:
Note In Microsoft Windows 2000 and Windows NT 4.0 Service Pack 4, the CIM is stored in %SystemRoot%\system32\wbem\Respository\cim.rep. In Windows Millennium Edition (Me), Windows 98, and Windows 95 OSR 2.5 operating systems, the CIM is stored in %windir%\system\wbem\Respository\cim.rep.
Although the CIM is based on object-oriented design principles, you need not become an expert in information modeling or schema design to be productive using WMI and writing WMI-based scripts. What is important is that you understand the basic structure and organization of the CIM, and how to navigate and interpret its contents.
WMI Scripting Library
The WMI scripting library provides the set of automation objects through which scripting languages, such as VBScript, Jscript, and ActiveState's ActivePerl access the WMI infrastructure.
The automation objects in the WMI scripting library provide a consistent and uniform scripting model for the WMI infrastructure. As demonstrated earlier, once you understand how to retrieve one managed resource type using the WMI scripting library, you can easily use the same steps to retrieve other WMI managed resources. For example, you can take any one of the three scripts presented earlier and easily modify the script to retrieve information about the processes (Win32_Process) running on a remote computer, processor (Win32_Processor) information, operating system (Win32_OperatingSystem) information, or any one of the hundreds of managed resources exposed by WMI.
The WMI scripting library is implemented in a single DLL named wbemdisp.dll, which physically resides in the %SystemRoot%\system32\wbem directory. The WMI scripting library also includes a type library named wbemdisp.tlb. You can use the WMI scripting type library to reference WMI constants from XML-based Windows Script Files, WSH scripts with a .wsf extension.
WMI Consumers
Consumers are the top layer. A consumer is a script, enterprise management application, Web-based application, or other administrative tool, that accesses and controls management information available through the WMI infrastructure.
(Consumer位于最顶层,一个Consumer可以是一个脚本、企业管理程序、基于Web的应用程序或其它的管理工具,它们都可以通过WMI结构来访问和控制权限内的管理信息。)
Note Many management applications serve dual roles as both WMI consumer and WMI provider. Such is the case with several Microsoft management products, such as Application Center, Operations Manager, and Systems Management Server.
Exploring the CIM
We've covered a fair amount of material, but there's one remaining detail we've not yet addressed, and that's how to determine what resources are exposed through WMI. Fortunately, you can use a number of different tools to browse the CIM schema and examine class definitions for WMI managed resources.
Some additional resources you should check out include:
WMI Tester (wbemtest.exe) Walkthrough
Now that you have some knowledge of the tools available to browse and explore the CIM, let's use WMI Tester (wbemtest.exe) to examine the Win32_Process class definition, and modify Listing 2 to retrieve several properties from the processes running on your local computer.
All for Now
Admittedly, we only scratched the surface of WMI scripting. To be completely honest, it was intentional. WMI provides so many scripting possibilities that it's easy to miss the forest for the trees. Don't worry, however; we'll fill in all the gaps as this series progresses. What's important to take away at this point is this: WMI is Windows' single most important management-enabling technology, and you need not be a developer or scripting guru(大师) to begin writing WMI-based scripts. Continue modifying your newly created script to retrieve additional process properties, or better yet, other managed resources. You just might find yourself with a toolbox full of custom system administration scripts before we meet next month. Let us know how you do.
Listing 4. Answer to WMI Tester walkthrough
strComputer = "." ' Dot (.) equals local computer in WMI
Set wbemServices = GetObject("winmgmts:\\" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("Win32_Process")
For Each wbemObject In wbemObjectSet
WScript.Echo "Name: " & wbemObject.Name & vbCrLf & _
" Handle: " & wbemObject.Handle & vbCrLf & _
" Process ID: " & wbemObject.ProcessID
Next
Scripting Clinic
Greg Stemp has long been acknowledged as one of the country's foremost authorities on scripting, and has been widely acclaimed as a world-class... huh? Well, how come they let football coaches make up stuff on their resumes? Really? He got fired? Oh, all right. Greg Stemp works at... Oh, come on now, can't I even say that? Fine. Greg Stemp gets paid by Microsoft, where he—tenuously—holds the title of lead writer for the System Administration Scripting Guide.
Bob Wells wanders around aimlessly espousing the virtues of scripting to anyone who will listen. Rumor has it, Bob's two dachshunds know more about scripting than most humans. In his spare time, Bob contributes to the System Administration Scripting Guide.
Ethan Wilansky spends a lot of his work time writing and consulting. He's crazy about scripting, Yoga, gardening, and his family (not necessarily in that order). He is currently working on a way to create script that will take out the trash and wash the dinner dishes.