How to Extend the Sms_def.mof File by Using the Windows Management Instrumentation Registry Providers

Archived content. No warranty is made as to technical accuracy. Content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Updated : June 14, 2002

Microsoft Product Support Services White Paper

Written by Mark A. Mears, Sr., MCSE

Abstract

Systems Management Server (SMS) uses the Sms_def.mof file to specify which hardware classes and attributes are collected and reported for hardware inventory. This white paper describes how to implement the Windows Management Instrumentation (WMI) Registry Providers by modifying the Sms_def.mof file to gather information from the registry on client computers. You can do this to gather information from the registry on SMS clients and to retain this information in the hardware inventory for creating queries and collections, and for targeting software distribution packages.

On This Page

Introduction
Phase 1: Registering the System Registry Provider
Phase 2: Defining a Registry Class with Properties and Qualifiers
Phase 3: Reporting Inventory for a New Hardware Class in SMS
Testing Your MOF file
Additional Notes
Sample MOF file Excerpts
For More Information

Introduction

There are three phases in creating a section of the Sms_def.mof file to enumerate a client's registry and to report that information back during an SMS Client Hardware Inventory process. These phases are:

  • Registering the System Registry provider

  • Defining a registry class with properties and qualifiers

  • Reporting Inventory for a new hardware class in SMS

Phase 1: Registering the System Registry Provider

Several different providers are defined and included with SMS 2.0. The instance provider and the property provider are the most useful for enumerating registry data and values with SMS. The differences between these providers include:

  • If the data that you want to report is contained in several subkeys in a registry location, you must use an instance provider. The strings that you define to search for are values in the subkeys in the location that is defined in the Property context of the .mof file. For example, if you want to return details about the installed network adapters in a computer, use an instance provider. The information that is returned contains the values that are enumerated for each of the subkeys. When you use an instance provider, you typically do not know how many subkeys exist under a particular key. However, these subkeys must have some values that are common to all of the subkeys. See the "Instance Provider Example" section of this document for an example.

  • If you want to retrieve values from a single registry location, you must define a property provider. In this case, you know the registry key from which you want to retrieve the values. See the "Property Provider Example" section of this document for an example.

Getting Started

The first task is to determine for which type of information that you are looking, and how that information is stored in the registry. You must determine whether the information is stored in a key or in a value. You can use Registry Editor (Regedit.exe or Regedt32.exe) to locate the key or value on the client to determine this information. This is important because it determines whether you use an instance provider or a property provider. After that, to complete phase 1, you paste the appropriate provider code in your new Management Object Format (MOF) file by using Notepad.exe. The actual text to use for both providers is included later in this document. You can paste the text into your file.

Note that the actual registry value that is retrieved is called the Property context. This value must have the same name as the registry value that you are enumerating. The name must be enclosed in quotation marks. The display name is the name by which the data will be referenced. MOF file syntax is derived from Microsoft® Visual C++® syntax for class definitions. Valid variable names (DisplayName variables) must start with a letter or an underscore (_).

Note: Some lines in the samples in this document may be automatically wrapped. When you paste a sample into Notepad or another text editor, make sure that the Word Wrap feature is turned off, and that no extraneous line breaks are present (such as a carriage return in the middle of a word).

Declaration and Creation of the Instance Provider

#pragma namespace("\\\\.\\root\\cimv2")
instance of __Win32Provider as $Instprov
{
     Name     ="RegProv" ;
     ClsID     = "{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}" ;
};
instance of __InstanceProviderRegistration
{
     Provider     =$InstProv;
     SupportsPut     =TRUE;
     SupportsGet     =TRUE;
     SupportsDelete     =FALSE;
     SupportsEnumeration =TRUE;
};

Declaration and Creation of the Property Provider

#pragma namespace("\\\\.\\root\\cimv2")
 // Registry property provider
instance of __Win32Provider as $PropProv2
{
Name ="RegPropProv" ;
ClsID = "{72967901-68EC-11d0-B729-00AA0062CBB7}";
ImpersonationLevel = 1;
PerUserInitialization = "FALSE";
}; 
instance of __PropertyProviderRegistration
{
Provider =$PropProv2;
SupportsPut =TRUE;
SupportsGet =TRUE;
};

Description of the Providers

In the first phase, you register the new provider class for later use. You do this to inform WMI which provider that you are using, and where WMI can locate the necessary information about the provider.

You must declare the namespace into which you will be adding the new class. You use the #pragma command to inform the MOF compiler that you will be using the specified namespace to add this object to. In this example, you enumerate the root \cimv2 namespace of the local computer. This is where the information for the new provider will be located. The Name attribute is an alias to the provider. In later sections, when you refer to the specific provider that you are using, you use this alias. The ClsID value is a registered class on the computer where Windows can locate the implementation of the provider class. The ClsID value refers back to the registered information to create a new instance of this class.

Note the extra backslash characters in the definition of the namespace. The first backslash character specifies a special character that follows. The second backslash character defines the special character that you want to use. This is known as "escaping" special characters so that the MOF compiler will interpret them literally.

Phase 2: Defining a Registry Class with Properties and Qualifiers

The classes that are used to hold registry data are defined with several standard properties:

  • Dynamic and Provider

    You can attach the Dynamic qualifier to either a class or an instance. The Dynamic qualifier marks the class or instance as being managed dynamically by a provider. When Dynamic appears on a class or instance, the Provider qualifier must also appear. The Provider qualifier identifies the provider that is responsible for managing the dynamic class or instance.

  • ClassContext

    The ClassContext qualifier is attached to a class. It specifies the path to the registry key that contains the information that the class represents. The ClassContext qualifier has the following format:

    Computer_Name|Subtree\\KeyPath

    The value for KeyPath can be long if it includes keys with subkeys. For example, the following ClassContext qualifier contains the path to a computer's transport devices (note that lines may be wrapped for readability):

    Computer_Name|HKEY_LOCAL_MACHINE \SOFTWARE

    \\MICROSOFT\\WBEM\\TRANSPORTS

The following template for a class definition illustrates using the Dynamic, Provider, and ClassContext qualifiers. The provider that is named by the Provider qualifier is the instance System Registry provider. Note that neither registry paths nor qualifier names are case sensitive.

[dynamic, provider("RegProv"), ClassContext("local|hkey_local_machine \software \microsoft \WBEM
transports\\Network Transport Modules")]
class RegTrans
{
  [key] string  TransportsGUID;
  [PropertyContext("Name")] string Name;
  [PropertyContext("Independent")] uint32 Enabled;
};

Sample

The following sample code demonstrates valid MOF file syntax for retrieving a resource descriptor (note that lines may be wrapped for readability):

[DYNPROPS] 
class MyRegProp
{    
   [KEY]  
   STRING MyKey; 
   STRING MyReservedTranslated;
};
[DYNPROPS] 
instance of MyRegProp
{
   MyKey = "1";
   [PropertyContext("local|hkey_local_Machine \hardware \ResourceMap \
   System Resources\\Reserved|.Translated(\"Internal\")(0)(1)(\"Memory.PhysicalAddress\")"),
   Dynamic, Provider("RegPropProv")] 
   MyReservedTranslated;
};

Phase 3: Reporting Inventory for a New Hardware Class in SMS

After you create a new class in the root\cimv2 namespace, add the class definition in the root\cimv2\sms namespace to specify inventory collection. Typically, you add your class and reporting information to the Sms_def.mof file. The Hardware Inventory agent uses the SMS_Report qualifier to determine which classes and properties to report.

The following example demonstrates how to add class and reporting information for a new HardwareAssets class.

// Add this class to the Sms_def.mof file. This class defines which
// properties to report to SMS.
[
     SMS_Report(TRUE), 
     SMS_Group_Name("Hardware Assets"),
     SMS_Class_ID("ACME|Assets|1.0")
]
Class HardwareAssets : SMS_Class_Template
{
     [SMS_Report(TRUE), Key] 
     string    AssetNumber;
     [SMS_Report(TRUE)] 
     string         OwnerName;
     [SMS_Report(TRUE)] 
     string         Location;
};

Testing Your MOF file

Follow these steps on a reference computer that you can use to check the integrity of the MOF file that you created. The reference computer must be an SMS client. After you verify the integrity of the MOF file, add the information to an Sms_def.mof file. It is a good idea to test the MOF file before you add the information to the Sms_def.mof file. If you do not, problems may adversely affect the SMS Hardware Inventory.

  1. At a command prompt, change to the folder in which you last saved your MOF file.

  2. Run the mofcomp.exe -check yourmofname.mof command. This checks the syntax of the MOF file that you created. A successful check generates this output:

    Microsoft (R) 32-bit MOF Compiler Version 5.1.3590.0

    Copyright (c) Microsoft Corp. 1997-2001. All rights reserved.
    Parsing MOF file: YourMofName.mof
    MOF file has been successfully parsed
    Syntax check complete.
    Done!

  3. If the check completes successfully, run the mofcomp.exe yourmofname.mof command. The new class is created in the root\cimv2 namespace.

  4. To verify, run Wbemtest.exe and connect to the root\cimv2 namespace. Then, recursively enumerate the classes. You must be able to find the class that you defined in your MOF file.

  5. After you find the new class that you created, double-click it to open the instance, and then click Instances. An object should be returned in the window. If this does not occur, there is a problem. Verify the following items if there is a problem:

    • If your MOF file defines a property provider, click Show MOF. The values that you are looking for should appear in the window.

    • If your MOF file defines an instance provider, the list of registry keys (items) that you configured the registry provider to look for should be returned when you click Instances. You can double-click each of these items and then click Show MOF to see additional details about what was successfully enumerated in the registry keys that exist under the PropertyContext registry location that is defined in the MOF file.

  6. If the data is returned successfully in step 5, you can add the contents of the MOF file to the Sms_def.mof file. Do this on the site server in the X:\SMS\Inboxes\Clifiles.src\Hinv\Sms_def.mof file, where X is the partition on which you installed SMS 2.0. Make sure to create a backup of the original file.

  7. Run the mofcomp –check sms_def.mof command on the copy that you created in step 6 to verify its integrity. After you do this, overwrite the production file with the copy. After you update the production copy of the MOF file on the site server, it is automatically copied to the client access points (CAPs). Note that when an SMS client receives an updated MOF file, an inventory resynchronization, or full inventory, occurs. In a large hierarchy with many SMS sites, it may be useful to stagger the rollout of a new Sms_def.mof file to avoid overloading the network or SQL server.

Additional Testing on an SMS Client

This information assumes that you have modified the site server's Sms_def.mof file with the new MOF information, and that the file has been propagated to the CAPs.

  1. Stop the SMS Client service, and then restart it.

  2. In Control Panel, double-click the Systems Management icon.

  3. On the Sites tab, click Update Configuration. This causes the new MOF file to be updated on the client. When this is completed, click Hardware Inventory on the Components tab, and then click Start Component.

  4. Monitor the client's Hinv32.log file for new updates. If it works correctly, you see lines in the log file that indicate that the CRC values for the CAP's version of the Sms_def.mof file differ from the client's version of the Sms_def.mof file. The new MOF file is then compiled.

Note: The Sms_def.mof file is stored in two locations on the client. If the update to the new Sms_def.mof file is not successful, the client uses the last version that was successful in these locations:

  • %Windir%\MS\SMS\Clicomp\Hinv

  • %Windir%\MS\SMS\Sitefile\%Sitecode%\Hinv

Sample Hinv32.log File

MOF changes detected, CRCs differ !!!

Purging SMS Delta Namespace ...

Compiling MOF. Command line: C:\WINNT\System32\WBEM\mofcomp.exe -AUTORECOVER C:\WINNT\MS\SMS\SITEFILE\FVL\hinv\SMS_DEF.MOF

Successfully compiled MOF for site XXX

At this point, enumerating the classes should indicate that the new class that you defined is successfully enumerated.

Additional Notes

  • Note that the MOF compiler cannot detect or correct any spelling errors. For example, if you misspell the registry location from which you are trying to retrieve information, running the mofcomp –check command does not return any error messages. The command seems to complete successfully. The MOF file also compiles successfully; you receive no error messages to indicate a problem. However, the information that you are looking for is not available by using either Wbemtest or SMS Hardware Inventory.

  • If some, but not all, of the information that you are looking for is being returned, you may want to use Registry Editor (Regedt32.exe or Regedit.exe) to determine if the information is actually contained in the registry location for the client for which the information is missing. In some cases, the registry keys on the client may not contain the information. This may also be the case if you compare the results from multiple computers and you see differences in the data that is returned.

  • If all of the clients are missing details on the same attribute, check in the registry to verity that the key that is being returned is actually populated with a value. If so, check the spelling to verify that the spelling of the entry is correct.

  • When a client processes the Sms_def.mof file, the client creates an .nhm file that contains the inventory that has been collected. This information is stored locally and is passed to the CAP by Copy Queue Manager on the client. The Inbox Manager Assistant thread on the CAP passes the .nhm file to the site server for processing by the SMS Inventory Processor thread. You can prevent the .nhm file from being passed to the site server so that you can view the contents of the file. To do this, stop the Inbox Manager Assistant thread, or stop the SMS Executive service on all of the servers with CAP roles in the site. The .nhm file is written to the CAP_XXX\Inventry.box folder on one of the CAPs for the site. View the contents of the .nhm file for the values that you intend to capture. If all processing is correct, open Resource Explorer for this computer in the SMS Administrator console and then enumerate the Hardware node. There should be a new entry for the class that you created and the information that you want to be enumerated.

Sample MOF file Excerpts

Instance Provider Sample

//=====================================================================
//Adding AddRemovePrograms
//=====================================================================
//=====================================================================
// Phase 1 Defined: Registering the System Registry Provider
//=====================================================================
#pragma namespace("\\\\.\\root\\cimv2")
instance of __Win32Provider as $Instprov
{
     Name     ="RegProv" ;
     ClsID     = "{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}" ;
};
instance of __InstanceProviderRegistration
{
     Provider     =$InstProv;
     SupportsPut     =TRUE;
     SupportsGet     =TRUE;
     SupportsDelete     =FALSE;
     SupportsEnumeration = TRUE;
};
//=====================================================================
// Phase 2 Defined: Defining a Registry Class with Qualifiers
//=====================================================================
[dynamic, provider("RegProv"),
ClassContext("local|HKEY_LOCAL_MACHINE \Software \
Microsoft \Windows \CurrentVersion \Uninstall")
]
class AddRemovePrograms
{
     [key]
     string     ProdID;
     [PropertyContext("DisplayName")]
     string DisplayName;
     [PropertyContext("Publisher")]
     string Publisher;
     [PropertyContext("DisplayVersion")]
     string Version;
};
//=====================================================================
//Phase 3 Defined: Reporting Inventory for a New Hardware Class
//=====================================================================
#pragma namespace("\\\\.\\root\\cimv2\\sms")
[SMS_Report(TRUE),
SMS_Group_Name("AddRemovePrograms"),
ResID(9100),ResDLL("SMS_RXPL.dll"),
SMS_Class_ID("MICROSOFT|ADDREMPROGS|1.0")]
class AddRemovePrograms : SMS_Class_Template
{
     [SMS_Report(TRUE),key]
     string ProdID;
     [SMS_Report(TRUE)]
     string DisplayName;
     [SMS_Report(TRUE)]
     string Publisher;
     [SMS_Report(TRUE)]
     string Version;
};

Property Provider Sample

// Adding CrashControl
//=====================================================================
//=====================================================================
// Phase 1 Defined: Registering the System Registry Provider
//=====================================================================
#pragma namespace("\\\\.\\root\\cimv2")
instance of __Win32Provider as $PropProv3
{
     Name ="RegPropProv" ;
     ClsID = "{72967901-68EC-11d0-B729-00AA0062CBB7}";
}; 
instance of __PropertyProviderRegistration
{
     Provider = $PropProv3;
     SupportsPut = TRUE;
     SupportsGet = TRUE;
}; 
//=====================================================================
// Phase 2 Defined: Defining a Registry Class With Qualifiers
//=====================================================================
[DYNPROPS] 
class CrashControl
{
     [key]string  Keyname="";
     string         CrashDumpEnabled;
     string       Dumpfile;
};
[DYNPROPS]
instance of CrashControl
{
     KeyName="CrashControl";
     [PropertyContext("local|HKEY_LOCAL_MACHINE \System \CurrentControlSet \Control
     CrashControl|CrashDumpEnabled"),
          Dynamic, Provider("RegPropProv")] CrashDumpEnabled;
     [PropertyContext("local|HKEY_LOCAL_MACHINE \System \CurrentControlSet \Control
     CrashControl|DumpFile"),
          Dynamic, Provider("RegPropProv")] DumpFile;
};
//=====================================================================
//Phase 3 Defined: Reporting Inventory for a New Hardware Class
//=====================================================================
#pragma namespace("\\\\.\\root\\cimv2\\sms")
     [SMS_Report(TRUE),
     SMS_Group_Name("CrashControl"),
     SMS_Class_ID("MICROSOFT|CrashControl|1.0")]
class CrashControl : SMS_Class_Template
{
     [SMS_Report(TRUE),key]
     string          KeyName;
     [SMS_Report(TRUE)]
      string          CrashDumpEnabled;
     [SMS_Report(TRUE)]
      string DumpFile;
};

For More Information

For the latest information about Systems Management Server 2.0, visit the following Microsoft Web sites: