Gathering WMI Data without Writing a Single Line of Code
At a Glance:
- Data available to WMI
- Simple command-line data collection in WMIC
- Formatting the output
Download the code for this article: WMIC2006_09.exe (151KB)
Can a command be your best friend? Maybe not, but it can make the job of administering Windows a whole lot easier. Writing scripts to take advantage of the power of Windows Management Instrumentation (WMI)
can be intimidating, but leveraging the relatively unknown command-line interface of WMI, called WMIC, makes it easier. What is WMIC, and why do I like it so much? Read on.
WMI is the Microsoft implementation of an industry-wide initiative called Web-Based Enterprise Management (WBEM), which defines standards for accessing and managing systems in an enterprise environment. WMI gives you control over many components of your systems, from the hardware all the way up to installed applications. You can use it to access event logs, operating system attributes, processes, installed applications, and much more. When you want to know the MAC address of a network card, the size of installed DIMMs, a list of running processes, user account information, installed operating system patches, and so forth, you can retrieve them via WMI. But getting all that information is not straightforward.
Before WMIC, the power of WMI was typically accessed via programs or custom scripts. For example, let's say you wanted to find out the type of CPU inside your system. In the past, you might have written a short VBScript script that uses WMI to query the name of the CPU on the local system:Then you'd execute the script using a command line like so:And the output of the script would look something like this:
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Processor",,48) For Each CPU in colItems Wscript.Echo "Name " & CPU.Name Next
cscript /NOLOGO cpuname.vbs
Look how easy it is to retrieve the same information using WMIC. Just type the following at a regular command prompt:Here's the output:
WMIC CPU GET NAME
Now that I've whetted your appetite, open a command window and type WMIC. The first time you do this, WMIC installs itself and drops you at a command prompt within the WMIC shell; your prompt changes to wmic:root\cli>. Start by typing /? to get a helpful listing of what you can do within WMIC. The help output (some of which is shown in Figure 1) is organized into two key sections: global switches and aliases. Try it on your own to see the full output.
[global switches] <command> The following global switches are available: /NAMESPACE Path for the namespace the alias operate against. /ROLE Path for the role containing the alias definitions. /NODE Servers the alias will operate against. /IMPLEVEL Client impersonation level. /AUTHLEVEL Client authentication level. /LOCALE Language id the client should use. /PRIVILEGES Enable or disable all privileges. /TRACE Outputs debugging information to stderr. /RECORD Logs all input commands and output. ... /?[:<BRIEF|FULL>] Usage information. For more information on a specific global switch, type: switch-name /? The following alias/es are available in the current role: ALIAS - Access to the aliases available on the local system BASEBOARD - Base board (also known as a motherboard or system - board) management. BIOS - Basic input/output services (BIOS) management. BOOTCONFIG - Boot configuration management. CDROM - CD-ROM management. COMPUTERSYSTEM - Computer system management. CPU - CPU management. CSPRODUCT - Computer system product information from SMBIOS. DATAFILE - DataFile Management. DCOMAPP - DCOM Application management. DESKTOP - User’s Desktop management. DESKTOPMONITOR - Desktop Monitor management. DEVICEMEMORYADDRESS - Device memory addresses management. ... For more information on a specific alias, type: alias /? CLASS - Escapes to full WMI schema. PATH - Escapes to full WMI object paths. CONTEXT - Displays the state of all the global switches. QUIT/EXIT - Exits the program. For more information on CLASS/PATH/CONTEXT, type: (CLASS | PATH | CONTEXT) /?
Global Switches are universal modifiers to the WMIC command line you'd like to execute, and aliases are references to the actual WMI data you'd like to manipulate.
When you try it on your machine, look through the alias section—it's packed with commands to get all sorts of great information. Perhaps you'd like to know which processes are running and the amount of memory they are using. That's simple enough—at the WMIC prompt, type:This gives you a dump of all the active processes on the system in a predefined, default layout (the same as if you had typed "process get" at the WMIC prompt). Notice all the information you receive for each process, organized in nice labeled columns. Scroll all the way to the right to make sure you don't miss anything. Of course, all this data may be more than you want. Once you know the columns you're interested in, you can select only those by using the get verb with names of the attributes. Perhaps all you want is the process name and the memory it is using. If you type the following, you'll get the output you see in Figure 2:
process get name, workingsetsize
Figure 2 Processes and the Memory They Use
Getting Data from Remote Systems
WMIC lets you access systems remotely as well as locally, which makes it extra useful for the busy administrator. To get the process listing from a remote system, simply add the /NODE: global switch followed by the remote computer name:You can provide the names of multiple computers in a command line at the same time if you like:In a multi-node query like this, it makes good sense to ask for the computer name as well, otherwise you might not know which system the process is running on. Here's how:The /NODE global switch can also accept the name of a text file containing a list of host names you'd like to access via your WMIC command line. Simply create the file and include system names or IP addresses, one system per line, and WMIC will process each entry. Here's the command to access a file called serverlist.txt:When processing WMIC commands against multiple systems, it's a good idea to use the /FAILFAST:on global switch, which tells WMIC not to wait around for an unresponsive host. Here is an example of how you could use the /FAILFAST switch to check the OS version on several systems:
/node:"server1" process get name, workingsetsize
/node:"server1","server2" process get name, workingsetsize
/node:"server1","server2" process get CSName, name, workingsetsize
/node:@serverlist.txt process get CSName, name, workingsetsize
/failfast:on /Node:johnkelnc6000, " johnkel-fer" os get Caption, CSDVersion, CSName
The default text output of WMIC is useful, but it's not exactly easy to read. WMIC supports a variety of output formats, including HTML, CSV, MOF, and XML. The two I use most often are CSV and HTML. CSV is perfect for manipulating data using Microsoft® Excel® or for importing into a database tool such as Access or SQL Server™. To generate a CSV formatted file, you simply use the /OUTPUT global switch, specify a file, and select the appropriate format:This generates output values separated by commas and written to the file c:\os.csv.
/output:c:\os.csv os get /all /format:csv
Note that WMIC doesn't add the double quotes that Excel uses to parse a typical CSV file, so you will likely have to open the file from within Excel and select the appropriate delimiter to properly parse the data (see Figure 3).
Figure 3 Data in Excel
Figure 4 HTML Output in Tabular Form
WMIC does a nicer job with HTML output and provides multiple ways to organize the output (see Figure 4). First let's output the same operating system data into a tabular format similar to the CSV file:
/output:c:\os1.html os get /all /format:htable.xsl
The output is the same as that in the CSV file, but formatted as HTML. This is useful when listing and evaluating multiple lines of similar data—perhaps for comparing operating system information for multiple systems. Here is the code that does that. Figure 5 shows the output:
/output:c:\os_list.html /Node:johnkelnc6000, "johnkel-fer", "johnkel-lhsrv" os get Caption, CSDVersion /format:htable.xsl
You can see how useful this tabular HTML format might be for retrieving and comparing information from multiple systems, processes, or volumes. Not all data is best displayed in tabular format, though. You may not want to scroll endlessly to the right to see data from queries with long lists of returned attributes. Instead, you can return data in a vertical format. For example, Figure 6 shows the output from the following query:
/output:c:\os2.html os get /all /format:hform.xsl
Figure 5 Side-By-Side Comparison in HTML
Figure 6 Data in a Vertical Presentation
Maybe you'd like to create a series of HTML reports that could be accessible at any time, showing the status of key servers. Perhaps you're not a coder or an HTML expert, but do write the occasional batch file. Figure 7 shows an example batch file I wrote to create an HTML index page of other HTML files generated using WMIC.
@Echo off rem rem rem The next few lines of echoes are to create the HTML to setup the page - rem I’ve added a bunch of carets to allow the required greater than and less than symbols to echo properly rem These echoes can be eliminated if you put all the required "header" HTML into a file and redirect it rem into the front of the target HTML file with a copy or type command - makes the batch file easier to read rem echo ^<HTML^>^<HEAD^>^<TITLE^>TechNet WMIC Monitoring Page Example^</TITLE^>^</HEAD^> >> list.html echo ^<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080"^> >> list.html echo ^<h1 align="center"^>^<b^>^<font face="Arial" size="+4" color="Red"^>TechNet WMIC Monitoring Page Example^</font^>^</b^>^</h1^> >> list.html echo ^<p align="center"^>^<table border="1" width="600"^> >> list.html rem rem Table headers on the page are defined here, should you want to add more... rem echo ^<tr^>^<td^>^<B^>Server Name^</td^> >> list.html echo ^<td^>^<B^>OS Info^</td^> >> list.html echo ^<td^>^<B^>Patches^</td^> >> list.html echo ^<td^>^<B^>Drive Volume Info^</td^>^</B^>^</tr^>^</p^> >> list.html rem rem rem The loop below does all the heavy lifting rem for /F %%i in (serverlist.txt) do ( echo Processing %%i... wmic /Failfast:on /node:"%%i" /output:"%%i_OS.html" OS Get /All /format:hform.xsl wmic /Failfast:on /node:"%%i" /output:"%%i_qfe.html" QFE where "Description<>’’" Get /All /format:htable.xsl wmic /Failfast:on /node:"%%i" /output:"%%i_drives.html" logicaldisk get caption, description, filesystem, size, freespace, compressed /format:htable.xsl echo ^<tr^>^<td^>%%i^</td^> >> list.html echo ^<td^>^<a href="http://%%i_OS.html"^>OS Info^</a^>^</td^> >> list.html echo ^<td^>^<a href="http://%%i_QFE.html"^>Patches^</a^>^</td^> >> list.html echo ^<td^>^<a href="http://%%i_drives.html"^>Drive Volumes^</a^>^</td^> >> list.html echo ^</tr^> >> list.html ) echo ^<p align="center"^>^<b^>^<font size="+1" color="Red"^> ^<BR^>Completed at >> list.html time /T >> list.html echo - on >> list.html date /T >> list.html echo ^</font^>^</b^>^<BR^>^</p^> >> list.html Echo . Echo DONE!!!
The batch file only looks complicated, because it contains all sorts of HTML tags that are used to create the properly formatted HTML index file (list.html). The core loop in the batch file is the key—here it is without any of the HTML mumbo jumbo or WMIC output switches:
for /F %%i in (serverlist.txt) do ( echo Processing %%i... wmic /Failfast:on /node:"%%i" /output:"%%i_OS.html" OS Get /All wmic /Failfast:on /node:"%%i" /output:"%%i_qfe.html" QFE where "Description<>''" Get /All wmic /Failfast:on /node:"%%i" /output:"%%i_drives.html" logicaldisk get caption, description, filesystem, size, freespace, compressed )
The loop simply reads though a text file (serverlist.txt) containing a list of system names (one per line) and calls WMIC to create uniquely named output files. The HTML output of the batch file looked like Figure 8. (Note that the batch file is available from the Code Downloads section of the TechNet Magazine Web site.
Figure 8 Output from Several Servers
Now you've seen how useful WMIC is for reporting, but it's handy for managing systems as well. I'll show you a few favorite time-saving tricks I use to control processes, make changes to network configuration, control services, and restart systems.
Using WMIC to stop and start processes on a system (remote or local) is a hugely useful capability. For instance, you could start a process on a remote system simply by typing the following:Sure, kicking off an instance of Notepad isn't that interesting, but it does make the point. Note that you'll be prompted to confirm the request. You could disable this prompt by setting the /INTERACTIVE global parameter to OFF.
/Node:"johnkel-fer" process call create "notepad.exe
Terminating processes is just as easy. Now that I have created all these instances of Notepad on my remote system, I'd like to get rid of them, so I issue this command:
wmic /interactive:off /node:"johnkel-fer" PROCESS WHERE NAME="notepad.exe" CALL Terminate
WMIC lets you terminate processes by name, rather than via process ID as you might have done in the past. This can be quite handy. Imagine you had an out-of-control process on multiple systems. Using WMIC combined with the process name and the list of system names or IP address, you could quickly shut down the rogue processes across your network. (Maybe not such a great idea—and an even better reason to carefully manage Administrative credentials in your enterprise.)
Note that I turned off interactive mode from outside of the WMIC command shell in batch mode from the command line (I preceded my request with WMIC, and it dropped back to the command prompt once the request completed). This is how you would automate the use of WMIC within a batch file, or as part of a scheduled process, rather than using interactive mode.
System Configuration Changes
All manner of system configuration options may be changed using WMIC. I find the NICCONFIG alias really useful. Perhaps you'd like to change a system from using a statically assigned IP address to leveraging DHCP without a desktop visit. You could look up the NIC card info using the following command:and change it to use DHCP (assuming the index number listed was 1) with the line:There are a number of other configuration settings for a network interface you can manage this way, such as the default gateway and WINS Servers.
WMIC nicconfig get description, DHCPEnabled, index
WMIC NICCONFIG WHERE Index=1 CALL Enable DHCP
Here's how to disable a service (Virtual Server in this case) on the local system:... and on more than one system:... and on a list of systems:What kind of tool would WMIC be if it didn't allow you to remotely reboot systems? Luckily, it does:
wmic service where "caption='Virtual Server'" call changestartmode disabled
wmic /interactive:off /Node:johnkelnc6000, "johnkel-fer" service where "caption='Virtual Server'" call changestartmode disabled
wmic /interactive:off /Node:@serverlist.txt service where "caption='Virtual Server'" call changestartmode disabled
wmic /interactive:off /Node:@serverlist.txt os WHERE Primary=True call reboot
As useful as WMIC can be, it is not a replacement for WMI scripts or more powerful management tools. You can't easily automate the manipulation of data accessible via WMIC—calculate the percentage of free disk space, for example. Pulling the same data via a Visual Basic® script may allow you to manipulate or filter it and act on information more easily in customizable ways. One other key limitation of WMIC I've found is the need for systems to be online to generate reports. It is wonderful to be able to interrogate systems and create HTML or other reports using WMIC, but it is not a management solution. It sounds silly to say, but it's hard to ask a system about its configuration if it is offline! Tools with persistent information storage coupled with robust reporting and alerting (such as SMS 2003 and Microsoft® Operations Manager) should be the core of every secure, well managed infrastructure. Still, for quick and easy access to system information, WMIC is hard to beat.
WMIC does provide a wonderful way to harness the power of WMI, and I've only scratched the surface here. There's still a great deal left for you to explore and discover on your own. New command-line and shell options are on the way for Windows, including the upcoming release of Windows PowerShell™ (formerly known as MONAD or MSH). PowerShell, with stunning new capabilities for managing and automating Windows systems, should be released later this year. Until it is generally available, WMIC can lighten your administrative burden.
Though WMIC is not available on Windows 2000, it can be used from a Windows XP or Windows Server 2003 system to access WMI—it even works to a limited degree with Windows NT, if WMI support is installed. WMI in Windows NT does not expose the event logs, so they may not be queried successfully from WMIC.
You’ll need a good amount of rights to use many of the capabilities of WMIC. Everything I’ve done in this article I did with full administrator rights. Also note that some aliases have not been implemented in both Windows XP and Windows Server 2003. The memorychip alias, for example, which can display the size and slots of memory modules (handy if you want to order RAM for an upgrade without opening up the system before hand) is not available in Windows XP.
If you want to read more about WMIC, check out these valuable resources:
John Kelbley is an Account Technology Specialist for Microsoft based in the Northeastern USA. He is the author of many poorly written VBScript and Perl scripts for server and workstation administration, many of which are obsolete since the introduction of WMIC. You can reach John at firstname.lastname@example.org.
© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.