Management

Advanced Client Inventories with SMS

Wes Dobry

 

At a Glance:

  • Using the SMS 2003 Hardware Inventory Agent
  • Expanding inventorying with MIF files
  • Dynamic vs. static MOF files

Download the code for this article: DobrySMSInventory2007_04.exe (152KB)

There comes a time in every administrator’s life when his boss asks for some information that can’t be collected without arduous amounts of work. But imagine being a proactive administrator

who was already collecting this data. You could supply your boss with the information instantaneously, thereby preventing unnecessary down time, avoiding overtime hours, and possibly even saving the company a lot of money. You could be a hero.

Out of the box, Microsoft® Systems Man­age­ment Server (SMS) 2003 collects a vast amount of information. But it doesn’t collect everything. For instance, SMS 2003 does not report by default on local groups and their members or local users and their attributes. Not having this information can be a problem if, say, a technician is putting Domain Users or, even worse, Everyone into the local administrators group on each system they work on. Or, say a company has no way of knowing what the local file and folder exclusion lists are on their corporate antivirus/anti-spyware solution. This may not seem like a major problem—until someone in IT realizes that users are putting c:\*.* in the exclusion list.

With the proper combination of scripting, Windows® Management Instrumentation (WMI), and SMS knowledge, you can expand SMS inventories to contain almost any morsel of information. This is made possible through the use of MIF (Management In­formation Format) and MOF (Management Object Format) files.

Taking Inventory

With SMS, organizations can perform customized deployments, monitor the targets, and maintain the deployed systems. By expanding SMS inventories, you can create and manage a much more customized target. For example, you can enforce corporate local security policies by deploying your security policies to systems that have had the policies modified by a user. You can also disable non-approved local user accounts and remove extraneous local administrators.

Of course, organizations also rely on SMS for getting timely, detailed information about client systems. Expanding the inventories allows you to create reports that contain completely custom information that isn’t readily available when relying solely on the default inventories. And the information can be very granular. For instance, you might create a report that contains the count of systems that have a specific registry key that points to a particular server farm. This would allow the administrators to assess approximately how many clients are pointed to each farm at any given time. Similarly, the security team can check to see which systems on the network are running a specific process that is known to be spyware.

The value of MIF and MOF files comes from the ability to input information from almost any source with a bit of translation. As long as the information is text-based, the information can be manipulated and placed into WMI with a MOF file, or collected in the form of a MIF file, and sent on the next hardware inventory cycle. Implementing an inventory expansion requires knowledge of VBScript or JScript®, as well as knowledge about what is to be collected. Considering that just about anything can be collected, this required knowledge can range from WMI to advanced SQL knowledge. Of course, SQL comprehension is a must no matter what type of information you are gathering, since you’ll need this knowledge when it comes to reporting on the collected data.

How Inventories Work

SMS contains two types of inventory processes: hardware and software. Software inventories only have information about files, such as where they are located, what versions they are, their size, and other file attributes. However, the software inventory process also allows you to collect files and store them on the site server.

Expansion of hardware inventorying is easily done since hardware inventories contain the largest array of information about a system. The information in hardware inventories is derived predominantly from WMI, the registry, and the system BIOS.

Hardware inventories are collected on a schedule, which is set in the Hardware Inventory Agent site settings on SMS 2003. Collections can be set to occur as often as once every minute to as infrequently as once every several months. Typically, you want to find a balance that collects this information at the fastest rate required by management but without taxing the network, site servers, management points, or clients.

When the Hardware Inventory Agent is first installed, it compiles the sms_def.mof file. This contains all the information that SMS initially collects. When this file is compiled, all the SMS namespaces and associated classes required for the Hardware Inventory Agent are created in WMI. Most of these are located in the \\.\root\CIMv2\SMS name­space. After installation, the Hardware In­vent­ory Agent looks through most of these classes to build the information that is then sent to the management point and eventually the site database.

MIF Files

In addition to pulling information from these WMI classes, the Hardware Inventory Agent looks for MIF files in the NOIDMIF and IDMIF collection folders. Any MIF files the agent finds in these locations are processed into the next hardware inventory.

MIF files provide the easiest way to expand the SMS Hardware Inventory. There are two types of MIF files—NOIDMIF and IDMIF files. These files are static, XML-like files that can contain almost any information a user could want to put into the SMS database. They can be created by any means used to create ordinary text files. Thus, these files can be created by most scripting languages, or just by hand.

Typically, MIF files are used in situations where the information is not contained in the registry or WMI, or when the information needs to be entered manually. These files can be created, for example, when your hardware deployment team delivers a new system. The deployment technician can navigate to an HTML application on the system and input all the asset information to be used to update an asset management database. That application then dynamically creates a NOIDMIF file and allows the technician to download the file to the NOIDMIF file collection folder. This NOIDMIF file can contain all the information entered by the technician and it is incorporated into the SMS database.

NOIDMIF and IDMIF files have only a few differences. An IDMIF file contains a unique header that provides architecture information and a unique ID. IDMIF files can be used to incorporate non-system devices into SMS as their own entities. For instance, a script can be used to create systems in SMS that are actually printers and write information about them into the SMS database.

NOIDMIF and IDMIF files are stored in standard locations, which are dictated by registry keys. Most of the time, they are %SYSTEMROOT%\sys­tem32\ccm\Inven­tory\NOIDMIF and ...\IDMIF, assuming that the SMS agent was installed in the default location. If the agent was installed in a custom location, the MIF directories should be in %CC­MAGENTINSTALLDIR%\Inventory\NO­IDMIF and ...\IDMIF. But if there is any doubt as to the locations of these directories, you can find the locations listed in the following registry keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\SMS\
Client\Configuration\Client Properties\NOIDMIF Directory

HKEY_LOCAL_MACHINE\Software\Microsoft\SMS\
Client\Configuration\Client Properties\IDMIF Directory

MIF files always have the same format, regardless of the information collected. Look­ing at the MIF file shown in Figure 1, you’ll see that the file is comprised of a single component that contains multiple groups and a single attribute in each group. All of the sections are required, though you do not need to have more than one group or attribute entry. You can look at it as if each group in the MIF file is a row in the data of the named section in the hardware inventory and that every attribute in the group is a column of that row.

Figure 1 LocalAdmins.mif

Start Component
  Name = “WORKSTATION”
    Start Group
        Name = “Local Admins”
        ID = 1
        Class = “Microsoft|LocalAdminsMIF|1.0”
        Start Attribute
            Name = “Account”
            ID = 1
            ACCESS = READ-ONLY
            Storage = Specific
            Type = String(100)
            Value = “Win32_UserAccount.Domain=’Contoso’,Name=’Domain Admins’”
        End Attribute
    End Group
    Start Group
        Name = “Local Admins”
        ID = 2
        Class = “Microsoft|LocalAdminsMIF”
        Start Attribute
            Name = “Account”
            ID = 1
            ACCESS = READ-ONLY
            Storage = Specific
            Type = String(100)
            Value = “Win32_UserAccount.Domain=’Contoso’,Name=’Technicians’”
        End Attribute
    End Group
    Start Group
        Name = “Local Admins”
        ID = 3
        Class = “Microsoft|LocalAdminsMIF”
        Start Attribute
            Name = “Account”
            ID = 1
            ACCESS = READ-ONLY
            Storage = Specific
            Type = String(100)
            Value = “Win32_UserAccount.Domain=’Example-PC’,Name=’Administrator’”
        End Attribute
    End Group
    Start Group
        Name = “Local Admins”
        ID = 4
        Class = “Microsoft|LocalAdminsMIF”
        Start Attribute
            Name = “Account”
            ID = 1
            ACCESS = READ-ONLY
            Storage = Specific
            Type = String(100)
            Value = “Win32_UserAccount.Domain=’Example-PC’,Name=’RandomUser’”
        End Attribute
    End Group
End Component

The sample LocalAdmin.vbs, which is shown in Figure 2, is a fairly simple VBScript. It looks up the NOIDMIF directory, deletes the temporary MIF file if it exists, creates the temporary MIF file, writes information collected via a simple WMI query recursively to the file, deletes the MIF file that exists in the NOIDMIF collection folder, and then finally moves the temporary NOIDMIF into the NOIDMIF collection folder.

Figure 2 LocalAdmin.vbs

On Error Resume Next

Const ForAppending = 8

Set objWshShell = CreateObject(“WScript.Shell”)
Set objFSO = CreateObject(“Scripting.FileSystemObject”)

strTempDir = objWshShell.ExpandEnvironmentStrings(“%TEMP%”)
strWinDir = objWshShell.ExpandEnvironmentStrings(“%WINDIR%”)
strComputerName = objWshShell.ExpandEnvironmentStrings(“%COMPUTERNAME%”)
strNoIDMifRegLocation = “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SMS\Client\Configuration\Client “ _
   & “Properties\NOIDMIF Directory”
strNoIDMifDirectory = objWshShell.RegRead(strNoIDMifRegLocation)
strMifFileName = “\LocalAdmins.mif”
strClassID = “Microsoft|LocalAdminsMIF|1.0”

If objFSO.FileExists(strTempDir & strMifFile) Then
   objFSO.DeleteFile(strTempDir & strMifFile)
End If

Set objMifFile = objFSO.OpenTextFile(strTempDir & strMifFileName, ForAppending, True)

objMifFile.Writeline “Start Component”
objMifFile.Writeline “ Name = “ & Chr(34) & “WORKSTATION” & Chr(34)

strWBEMQuery = “SELECT partcomponent FROM win32_groupuser WHERE groupcomponent = “ & Chr(34) _
   & “\\\\” & strComputerName & “\\root\\cimv2:Win32_Group.Domain=\” & Chr(34) & strComputerName _
   & “\” & Chr(34) & “,Name=\” & Chr(34) & “Administrators\” & Chr(34) & Chr(34)

Set objWBEM = CreateObject(“WbemScripting.SWbemLocator”)
Set objWBEMServer = objWBEM.ConnectServer(, “root\cimv2”)
Set colResults = objWBEMServer.ExecQuery(strWBEMQuery)

i = 1
For Each objItem in colResults
         objMifFile.Writeline “ Start Group”
         objMifFile.Writeline “ Name = “ & Chr(34) & “Local Admins” & Chr(34)
         objMifFile.Writeline “ ID = “ & i
         objMifFile.Writeline “ Class = “ & Chr(34) & strClassID & Chr(34)
         objMifFile.Writeline “ Start Attribute”
         objMifFile.Writeline “ Name = “ & Chr(34) & “Account” & Chr(34)
         objMifFile.Writeline “ ID = 1”
         objMifFile.Writeline “ ACCESS = READ-ONLY”
         objMifFile.Writeline “ Storage = Specific”
         objMifFile.Writeline “ Type = String(100)”
         strUserName = objItem.PartComponent
         strUserName = mid(strUserName, instr(1, strUserName, chr(58)) + 1)
         If Instr(1, strUserName, Chr(92), 1) > 0 Then 
                  strUserName = Replace(strUserName, Chr(92), Chr(92) & Chr(92), 1, -1, 1)
         End If
         If Instr(1, strUserName, Chr(34), 1) > 0 Then
                  strUserName = Replace(strUserName, Chr(34), Chr(39), 1, -1, 1)
         End If

         objMifFile.Writeline “ Value = “ & Chr(34) & strUserName & Chr(34)
         objMifFile.Writeline “ End Attribute”
         objMifFile.Writeline “ End Group”
         i = i + 1
Next

objMifFile.Writeline “End Component”
objMifFile.Close

If objFSO.FileExists(strNoIDMifDir & strMifFileName) Then
   objFSO.DeleteFile(strNoIDMifDir & strMifFileName)
End If

objFSO.MoveFile strTempDir & strMifFileName, strNoIDMifDir & strMifFileName

While MIF files provide an easy way to expand the SMS Hardware Inventory, there are some issues to consider when using them. MIFs are processed in every hardware inventory cycle. But since these files are created, collected, analyzed, and then finally put into inventory, the information contained in a MIF can be delayed from showing up in the inventory by up to one hardware inventory cycle. This means that if a company has one-day hardware inventory cycles, the data in their site database could be up to two days behind. Therefore, you must carefully consider when the programs that create MIF files are advertised and when the hardware inventory cycle runs.

Say a company named Contoso has one-day inventory cycles that run at midnight. On Monday at 1:00 AM, a VBScript runs, creating a NOIDMIF file that contains the output of a rootkit scanner. This output is collected at midnight and reported to the management point. The Contoso SMS administrator then looks at the information on Wednesday evening at about 10:00 PM and finds that the information is 45 hours old. This is because the SMS administrator didn’t put thought into when to advertise the program used to create the NOIDMIF file.

MOF Files

MOF files are more complicated than MIF files. And they have an advantage over MIFs in that they input their information directly into WMI and become part of the hardware inventory agent’s standard data collection process. Thus, you may not have to advertise a VBscript over and over to get information, saving you time and hassle. You can instead advertise the MOF once per computer and it is then compiled.

MOF files also have the advantage of the information being just as current as the rest of the information in the hardware inventory. Every time the Hardware Inventory Agent goes through its cycle, the classes and providers detailed in the MOF file are queried and the information is returned quickly. When you need information quickly, you can execute a package that contains your MOF file and a VBScript, kicking off a hardware inventory. The information you need is then acquired in as little as one advertised program policy cycle.

There are three classifications of MOF files: MOF files for an existing WMI class and namespace, MOF files for an additional class with an existing WMI provider, and MOF files for an additional class that does not have a WMI provider.

MOF files contain two parts. The first part is the namespace definition section. This is where the WMI provider information is identified. The second section contains SMS reporting attributes. This section tells the Hardware Inventory Agent where to look for and process the information contained in the WMI classes mentioned. Since MOF files deal directly with WMI, I recommend that you take some time and look into the Microsoft WMI Software Development Kit (SDK) if you plan to work with these files (see go.microsoft.com/fwlink/?LinkID=83121 for more information).

Each of the aforementioned classifications of MOF files can be either static or dynamic. For example, you would have a static MOF file if you had the company’s build procedure compile a MOF file that contained information regarding who built the system, what build of servers they used, what the initial build versions were, the date on which the machine was built, and so on. This information never needs to be updated and therefore the information can be put directly into the MOF file and compiled into WMI using mofcomp.exe. After this occurs, the area in which the Hardware Inventory Agent is looking needs to be expanded by adding the group and class information into the sms_def.mof file on the site server.

A dynamic MOF file is similar to a static MOF file except that instead of writing collected information directly into WMI, data is collected via a WMI provider. A WMI provider is a plug-in that allows an application or service to directly input information into WMI. This provider allows dynamic access into other areas of WMI and the system, such as the registry, file locations, and Windows Installer information

In terms of working with MOF files, the easiest way to enhance the hardware inventory is to have the inventory catalog more information that already exists in WMI. This can be done by extending the sms_def.mof or turning on additional reporting classes that are currently disabled. The sms_def.mof file is located in the \\siteserver\SMS_<sitecode>\inboxes\clifiles.src\hinv folder. All the devices in the company will pull the new sms_def.mof on their next machine policy cycle and begin collecting and reporting the information.

Next in line, in terms of difficulty, is using an existing WMI provider but creating a new class. An example of this approach is shown in Figure 3. In this example, by using the built-in registry provider, the class CU_Desktop is created with a dynamic property querying HKEY_CURRENT_USER\Control Panel\Desktop\Wallpaper on the local device. After this MOF file is compiled on the client, the information contained in SMS_Def_Extension.mof (see Figure 4) needs to be appended to sms_def.mof. The file contains information regarding whether SMS should report on it, the group name, the class ID, what class the Hardware Inventory Agent should look in WMI to find the information to report on, and finally, the actual values.

Figure 4 SMS_Def_Extentions.mof

#pragma namespace ("\\\\.\\root\\CIMv2\\sms")
 [ SMS_Report    (TRUE),
  SMS_Group_Name ("Current User Desktop"),
  SMS_Class_ID   ("MICROSOFT|CU_Desktop|1.0") ]
class Power_Mgmt : SMS_Class_Template
{
    [SMS_Report(TRUE),key]
        string  index;
    [SMS_Report(TRUE)]
    sint32   CurrentUserDesktop;
};

Figure 3 CurrentUserDesktop.mof

#pragma namespace(“\\\\.\\root\\CIMv2”)
// Registry property provider
instance of __Win32Provider as $PropProv
{
    Name    =”RegPropProv” ;
    ClsID   = “{72967901-68EC-11d0-B729-00AA0062CBB7}”;
    ImpersonationLevel = 1;
    PerUserInitialization = “FALSE”;
};
instance of __PropertyProviderRegistration
{
    Provider       =$PropProv;
    SupportsPut    =TRUE;
    SupportsGet    =TRUE;
};
[DYNPROPS]
class CU_Desktop
{
    [key]
    string  index = “current”;
    sint32 CurrentUserDesktop;
};
[DYNPROPS]
instance of CU_Desktop
{
     [PropertyContext(“local|HKEY_CURRENT_USER\\Control Panel\\Desktop|Wallpaper”),
        Dynamic, Provider(“RegPropProv”)]
        CurrentUserDesktop;
};

MOF files also have the ability to access information provided by WMI providers that are not included by default on systems. In order to use these providers, the WMI provider must first be distributed and installed before the MOF file is compiled on the client and sms_def.mof extended.

Wrapping Up

MIF and MOF files are powerful tools for quick and substantial information collection. These file formats provide the framework for easily introducing information into the SMS database without directly modifying the tables. With enough imagination, almost anything can be inventoried and reported on. Even better, problem situations can be avoided, as administrators can act proactively to gather vital information.

Understanding MIF and MOF files takes some time. However, there are helpful resources available that can assist you in learning how to make use of these files. For starters, check out the WMI documentation and SDK, as well as the Systems Management Server 2003 Operations Guide. If you put the effort into understanding these concepts, what you get out of expanded SMS inventorying will far outweigh what you put into it.

Wes Dobry is located in the Orlando, Florida area where he works as a consultant and as a Network Administrator for a large healthcare firm. Contact him at wesdobry@wesdobry.com.

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.