Downloads
20138.zip

For some systems administrators, Windows Management Instrumentation (WMI) might seem miraculous—an answer to their prayers for a solution that lets them perform tasks in all facets of their networks. As I discussed last month, WMI consists of dozens of different classes that represent the functionality of a machine or an OS. With so many classes from which to choose, you can create a Perl script that can perform just about any administrative task. For example, you can discover the service pack installed on an OS, calculate how much physical memory an OS has, and create a shared directory.

Obtaining the Service Pack Version
Systems administrators who use Win32 Perl code can tell you that determining an OS's installed service pack is difficult. However, WMI's Win32_OperatingSystem class makes this task easy. This class describes a computer's OS, so you can use it to obtain the service pack version.

I've written a script, WOS.pl, that obtains not only the service pack version but also other information about an OS, such as its name, type, and amount of virtual memory. Listing 1 contains the main body of WOS.pl. As the code at callout A in Listing 1 shows, the script connects to the target machine's WMI service. The last three lines in callout A specify a security level that allows the script to work on Windows NT and Windows 9x machines running WMI 1.0. In WMI 1.5, the impersonation level defaults to Impersonate on all Windows platforms, so you don't need these lines. However, including them doesn't affect the script's execution. (For more information about connecting to the WMI service, see last month's column.)

After connecting to the WMI service, the script iterates through each instance of the Win32_OperatingSystem class. Typically, you have only one instance of this class because only one OS can run on a machine at a time. The script extracts various properties from this WMI class instance, which the $OS variable represents. The extracted properties include Caption, OSType, CSDVersion, and TotalVirtualMemorySize.

Caption. The Caption property returns a string that identifies the OS.

OSType. The script uses the OSType property to obtain the type of OS that's running on the machine. However, the property returns a numeric index value. To provide more user-friendly information, the script uses an array (@OS_TYPE). The index to the @OS_TYPE array matches the value of the OSType property.

CSDVersion. This property returns the Corrective Service Disk (CSD) version number. (CSD is another way to refer to a service pack.) Thus, this property specifies the version of the service pack installed on the target machine.

TotalVirtualMemorySize. This property returns the total amount of virtual memory, not physical memory. Unfortunately, the Win32_OperatingSystem class doesn't have a property that tells you how much physical memory is installed on a machine. The property that comes closest is the TotalVisibleMemorySize property, which specifies how much RAM the OS is aware of. However, the value that TotalVisibleMemorySize returns doesn't include any RAM that a motherboard might reserve for video or other applications. In addition, some NT and Win9x machines might miscalculate the TotalVirtualMemorySize value. Thus, you need to double-check this value against the actual size the first time you use this property.

After the script retrieves the properties' values, it passes them to the DumpInfo() function. This function then formats the information and writes it to the console window.

You can find WOS.pl in the Code Library on the Windows Scripting Solutions Web site (http://www.winscriptingsolutions.com). To run WOS.pl on a local machine, type

perl WOS.pl

at the command line. To run WOS.pl on a remote machine, type

perl WOS.pl MyMachine

where MyMachine is the remote machine's name. The user account and password on the remote machine need to be the same as the user account and password you're using locally; otherwise, the script is denied access.

Calculating the Amount of Physical Memory
As I just noted, you can't use the Win32_OperatingSystem class to report the amount of physical memory on a machine. However, the WMI Win32_PhysicalMemory class provides information about the physical memory that exists on a machine.

A machine has an instance of the Win32_PhysicalMemory class for each memory device. For example, my notebook has an instance for the 32MB of memory soldered into the motherboard and an instance for the 64MB add-on memory card. My desktop machine has three instances—one for each DIMM installed.

Win32_PhysicalMemory exposes the Capacity property, which represents the number of bytes that the memory device provides. Even if a machine uses SIMMs and requires you to add SIMMs in pairs, each SIMM has an instance of the class. So, if you have 64MB of RAM provided by a pair of 32MB SIMMs, you have two instances, each with a Capacity property of 33,554,432 bytes.

To discover how much memory your computer has, you can add the Capacity properties from all the instances of the Win32_PhysicalMemory class. The script WMemory.pl in the Windows Scripting Solutions Code Library does just that. WMemory.pl is similar to WOS.pl, except that the script accesses a different class and its properties. WMemory.pl walks through each instance of the Win32_PhysicalMemory class to display several interesting properties, including the Capacity, DataWidth, TotalWidth, and Speed properties.

The DataWidth property specifies the number of bits used to represent the data on the memory device. The TotalWidth property specifies the total number of bits used to represent data on the memory device. Typically, the DataWidth and TotalWidth values are the same. Different values often mean that the device has Error-Correcting Code (ECC), which is important to know if you plan to add memory to a machine because you usually don't mix ECC and non-ECC memory. Thus, WMemory.pl compares the DataWidth and TotalWidth values in addition to adding the Capacity properties to determine the amount of physical memory.

The Speed property tells you the speed a memory device uses. Older machines might not report a value or might report an incorrect value for this property because they don't expose information about a memory device's speed.

To run WMemory.pl on a remote machine, type

perl WMemory.pl MyMachine

at the command line, where MyMachine is the remote machine's name. If you want to run the script on the local machine, don't include a machine name.

Knowing how to enumerate a memory device's properties is important because you can obtain detailed information about that device. However, there's an easier way to discover the total physical memory on your machine. Replace the Win32_PhysicalMemory class with the Win32_ComputerSystem class, then query the TotalPhysicalMemory property. This value represents all the physical RAM on that machine. Although the returned information isn't as detailed, this approach is much easier.

WMI Isn't Only About Properties
The examples I've discussed so far use WMI class properties. However, WMI classes are more than collections of properties. Some classes have methods that you can call to perform actions. For example, the Win32_OperatingSystem class contains three methods: Reboot(), Shutdown(), and Win32Shutdown(). As their names imply, you use these methods to reboot or shut down a machine. Let's look at an example of how you can use WMI class methods in a script.

Creating a Shared Directory
The Win32_Share class represents shared directories and other devices (e.g., printer queues, communication devices) on a machine. This class exposes the Create() method. As the script WShares.pl in Listing 2 shows, you can use this method to create a shared directory on a machine. You can run WShares.pl so that it either lists existing shares or creates a shared directory.

Listing shares. Callout B in Listing 2 highlights the part of the script that lists all the existing shares on a machine. This part of the script is similar to the other two scripts I've discussed. WShares.pl walks through each instance of the Win32_Share class and extracts the Type, Name, Path, and Description property values. The script uses the Type value to determine whether an instance of the Win32_Share class represents an administrative share (i.e., default shared root directories, such as c$ and d$), which the value ­2147483648 specifies. If the instance is an administrative share, the script proceeds to the next instance. If the instance isn't an administrative share, the script prints that instance's Name, Path, and Description property values.

To use WShares.pl to list shared directories, type

perl WShares.pl MyMachine

at the command line, where MyMachine is the name of the remote computer for which you want to display the shares. If you don't pass in a computer name, the script displays the local shares.

Creating a shared directory. Callout C in Listing 2 highlights the part of the script that creates a shared directory. The script requests the base Win32_Share object, then creates a shared directory. To create a directory, the Create() method uses up to six parameters: directory, name, type, maxusers, comment, and password. The parameters are self-explanatory, except for the type parameter. This numeric value specifies the type of object you want to share. Typically, this value is 0, which specifies a directory.

The directory, name, and type parameters are mandatory, whereas the maxusers, comment, and password parameters are optional. When you run WShares.pl, you need to pass in the mandatory parameters, except for type, which is hard-coded into the script, and any optional parameters you want to use. The code at callout A in Listing 2 lets you pass in the parameters as switches at the command line. The switches take the format -x, where x is the first letter of the parameter name. For example, if you type

perl WShares.pl MyMachine
        -n NewShareName
        -d C:\temp
        -c "The share's comment"

the script creates a shared directory named NewShareName in C:\temp on the remote computer called MyMachine. The share's description is The share's comment. If you don't specify the machine name (i.e., MyMachine), the script creates the share on the local machine.

Such Power, Such Possibilities
By now, it should be obvious that WMI rocks—and I've covered only the fundamentals thus far. If you administer Win32 machines, you need to learn more about this technology. Read articles and books, search the Web, write code, or do whatever you need to do to learn about WMI.