A File as Seen from WMI
Windows Management Instrumentation (WMI) is a technology that ships with all current Microsoft operating systems. It can also be retrofitted to Windows NT, Windows 98, and Windows 95. Compared to Active Directory, the Microsoft Management Console, or even the new Windows Device Driver Model, WMI has received relatively little media attention, yet it has the potential to transform the lives of systems administrators responsible for Windows-based networks. The reason? For the first time, it provides a consistent, comprehensive and scriptable interface to the various components and subsystems that make up a Windows-based computer. Within the WMI world, an entire computer system is seen as simply a set of interconnected objects, each of which yields information about and allows manipulation of the component it represents. Thanks to WMI, a whole load of repetitive, mundane tasks, such as checking Event Logs for certain kinds of events, ensuring that server disks do not become full, archiving old files, and generally monitoring running systems, can all be automated with an easily learnable scripting language such as VBScript.
Over the last few months, an encouraging number of articles have appeared, explaining the concept of WMI, its overall structure, the way objects are related to each other, and the underlying technologies. Others have presented clever scripts that use WMI to perform various types of systems management tasks. However, for a systems administrator who is not too familiar with scripting but who wants to begin learning about WMI, a couple of simple questions are rarely answerednamely, "What is a WMI object?" and "How can I use VBScript to play with a WMI object?"
In this article, adapted from Windows Management Instrumentation (Lavy and Meggitt, New Riders), Matthew Lavy attempts to answer these questions in a hands-on, practical way by focusing on just one type of WMI objectnamely, the WMI representation of a file. An exploration of a WMI file object and the way in which it can be interrogated and manipulated from VBScript serves as a down-to-earth introduction to WMI objects and the VBScript needed to interact with them. This article assumes a basic knowledge of VBScript and a general understanding of WMI.
Representing a File in WMI
A file is represented in WMI by a CIM_DataFile object. Every file on a Windows 2000 system is represented by one of these objects. In common with all WMI objects, each CIM_DataFile object can be uniquely identified by a primary key, its Name property. In the case of CIM_DataFile objects, the Name property contains a string value representing the fully-qualified path to the file being represented. For example, the object representing boot.ini, a file that can be found in the C: directory of all standard Windows 2000 machines, has the name "c:\boot.ini".
Using VBScript, you can retrieve a reference to a CIM_DataFile object representing c:\boot.ini with the following code fragment:
Set refFile = GetObject("winMgmts:CIM_DataFile.Name='c:\boot.ini'")
This code tells VBScript to ask the winMgmts service (that is, WMI) to find an object of type CIM_DataFile whose name is 'c:\boot.ini'. In reality, the object is not so much "found" as "created," because CIM_DataFile objects are dynamic: WMI creates them as and when they are needed.
As soon as you have a reference to a CIM_DataFile, it is easy to find out most of that file's vital statistics, because these are exposed as properties of the object. For example, you can find out the size, attributes, and creation, modification, and access dates of boot.ini using this simple code example:
Set refFile = GetObject("winMgmts:CIM_DataFile.Name='c:\boot.ini'") 'output the file's name and size Wscript.echo "File name is: " & refFile.Name Wscript.echo "File size is: " & refFile.FileSize & " bytes" 'use conditional execution to report on any set attributes If refFile.Archive then WScript.echo "The archive bit is set" If refFile.Hidden then WScript.echo "This file is hidden" If refFile.System then WScript.echo "This is a system file" 'output date information Wscript.echo "The file was created on: " & refFile.CreationDate Wscript.echo "The file was last modified on: " & refFile.LastModified Wscript.echo "The file was last accessed on: " & refFile.LastAccessed 'tell VBScript we have no more use for the object Set refFile = Nothing
This is a complete, executable script. Type it into a text editor and save it with a .vbs extension. You can then run it using the Windows Scripting Host, preferably in command-line mode. If the preceding sentence does not mean anything to you, open a command shell and type cscript script.vbs, where script is the name of the file you just saved.
Having retrieved a reference to the WMI object that represents c:\boot.ini, the script extracts information by reading its properties. Most of the information is textual (such as Name) or numerical (such as FileSize) and can be displayed directly using WScript.echo. Note that the Archive, Hidden, and System properties, in contrast, are Boolean: They return either true or false. Although you could type WScript.echo "Archive bit:" & refFile.Archive (and, in this case, cause the script to display Archive bit: false), it's much neater to take advantage of the Boolean nature of the Archive property and use a conditional in the code:
If refFile.Archive then WScript.echo "The archive bit is set"
This code displays The archive bit is set if and only if refFile.Archive returns a value of true. Note that as the last step in the script, you set refFile to the special value of Nothing, telling VBScript that you no longer need a reference to the object and that resources allocated to it can be released.