Roger Zander at myITforum.com

How to create a C# WMI-Provider

Creating a WMIProvider in C# using the WMI Provider Extension from .NET Framework 3.5 is not a big thing and it requires only a few additional lines of code.
A lot of SMS/SCCM administrators do have the requirement to inventory the members of the local administrators group, that’s why I will do an example for this scenario, but it can be easy adapted to report whatever you want….

First at all: If you do not have .NET 3.5 SP1, you should first register the “System.Management.Instrumentation.dll” as described in How to: Fix Provider Load Failure Error.

1.  Create a new Class Library Project in VS2008 and verify the project is using the .NET Framework 3.5.

2.  Add the “System.Management.Instrumentation” namespace to the references and to the using directives:
using System.Management.Instrumentation;

3.  Above the Namespace keyword, you have to declare the WMI Namespace which should contain our new dynamic WMI Class:
[assembly: WmiConfiguration(@"root\cimv2", HostingModel = ManagementHostingModel.LocalService)]
In our case, the provider must be able to enumerate all local administrators, that’s why I'm using the “Local Service” security context.

4.   You have to tag the C# Class to provide WMI informations and you have to specify the WMI Class Name:
[ManagementEntity(Name = "Win32_LocalAdmins")]

The complete code looks now like this:
using System;

using System.Collections.Generic;

using System.Text;

using System.Management.Instrumentation;

 

[assembly: WmiConfiguration(@"root\cimv2", HostingModel = ManagementHostingModel.LocalService)]

namespace ClassLibrary1

{

    [ManagementEntity(Name = "Win32_LocalAdmins")]

    public class Class1

    {

    }

}

5.  Now, you have to declare the attributes of our “Win32_LocalAdmins” WMI Class. Let’s create three Attributes:  the Name of the local admin group members, the Type (User or Group) and the SID. The “Member” attribute will become a Key property:
 [ManagementEntity(Name = "Win32_LocalAdmins")]
    public class Class1
    {
        [ManagementKey]
        public string Member { get; set; }
        [ManagementProbe]
        public string Type { get; set; }
        [ManagementProbe]
        public string SID { get; set; }
    }

6.  To fill up the class with values, we need to define a Constructor:
     public Class1(string sMember, string sGUID, string sType)
        {
            Member = sMember;
            SID = sGUID;
            Type = sType;
        }

7.   The missing part now is the code which will be executed if the WMI Class is enumerated. So you have to declare a function of the type IEnumerable:
[ManagementEnumerator]
static public IEnumerable GetAdmins()
{ // GetAdmin Code }
The code should create new instances of Class1 for each member of the local adming group by using the Constructor of Class1:
return new Class1(Name, SID, Type)

Note: Download the attached VS2008 Project to see the complete code behind "GetAdmins()".
 
That’s all you need to create a dynamic WMI Class ... But how to Install the WMIProvider ?  
You have to create an Installer class and it would make sense to provide a way to uninstall the „Win32_LocalAdmins“ class:

    [System.ComponentModel.RunInstaller(true)]
    public class MyInstall : DefaultManagementInstaller
    {
        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);
            System.Runtime.InteropServices.RegistrationServices RS = 
                new System.Runtime.InteropServices.RegistrationServices();
        }

        public override void Uninstall(IDictionary savedState)
        {
            try
            {
                ManagementClass MC = 
                    new ManagementClass(@"root\cimv2:Win32_LocalAdmins");
                MC.Delete();
            }
            catch { }
            try
            {
                base.Uninstall(savedState);
            }
            catch { }
        }
    }

Now, you have to copy the library to the Global Assembly Cache by using the Command:
gacutil.exe /i „<Path>\classlibrary1.dll“

The WMIProvider can now be installed with the command:
InstallUtil.exe /i “<Path>\classlibrary1.dll”

Both last manual actions can be easy integrated in a Windows Installer Setup Project.

 

Done... If you start "wmic.exe path win32_LocalAdmins" you should get a list with all the members of your local administrators group:
wmic:root\cli>path Win32_LocalAdmins
Member         SID                                            Type
Administrator  S-1-5-21-3333231195-3254942849-1953328938-500  User

 

The complete VS2008 Project can be downloaded at:

http://myitforum.com/cs2/blogs/rzander/LocalAdminWMIProvider.zip

Comments

jibutoms said:

Great Article.. Thanks...

# May 7, 2009 3:07 AM

Tiles said:

Thanks for the article, I'm currently doing a chapter on WMI for my MCTS course and this was a great little intro.

# December 2, 2009 12:36 PM