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