A downloadable file for this article is available here.
The sample downloadable solution (zip) is entirely developed using Visual Studio.NET 2003 Enterprise Architect on Windows Server 2003 Standard Edition. But, I am confident that it would work with other versions of Windows (which support .NET 1.1) versions as well.
Some global routines used for my WMI development
Let me first address some issues. I received a lot of feedback from several readers throughout the world on my series “WMI Programming with Visual Basic.NET”. Almost every one (about 80%) requested that I extend the series with much more useful and helpful information about working with WMI (in the form of tasks). Some of the readers also asked me to give examples on VBScript as well (and not only VB.NET).
One should consider that WMI is being updated and enhanced almost every day. Microsoft is also integrating WMI directly into some of its products. With humble thanks to every reader who encouraged me to write more, I further extend the same series (but with a different naming scheme). I will be including much more useful information, both for developers and system administrators.
I keep on extending the same series as much as possible, covering almost all the aspects of WMI. I strongly suggest you go through my series on “WMI Programming with Visual Basic.NET” before reading this article. The series even covers “event handling” using WMI with Visual Basic .NET in the form of Windows Service.
For flexibility in retrieving WMI information (using VB.NET), I frequently used the following simple global routines which would help me to work with other areas of development very easily.
Public Sub addRow(ByRef dt As DataTable, ByVal p As String, ByVal v As String)
Dimdr As DataRow
dr = dt.NewRow
dr("Property") = p
dr("Value") = v
dt.Rows.Add(dr)
End Sub
Public Function getStructure() As DataTable
Dim dt As New DataTable
dt.Columns.Add(New DataColumn("Property"))
dt.Columns.Add(New DataColumn("Value"))
Return dt
End Function
Two of my global routines are “getStructure” and “addRow”. Both are generally used if I have the “Property->value” scenario. “GetStructure” just creates a data table structure and “AddRow” just adds a data row for every data table passed to it. And similarly, I also have the following two, to work with “UserAccountInformation”.
Public Function getUserAccountStructure() As DataTable
Dim dt As New DataTable
dt.Columns.Add(New DataColumn("FullName"))
dt.Columns.Add(New DataColumn("Name"))
dt.Columns.Add(New DataColumn("Domain"))
dt.Columns.Add(New DataColumn("LocalAccount"))
Return dt
End Function
Public Sub addUserAccountRow(ByRef dt As DataTable, ByVal FullName As String, ByVal Name As String, ByVal Domain As String, ByVal LocalAccount As String)
How can you find out information about your server? By this I mean its name, domain, workgroup, and so on. The following VB.NET code should supply some minimum information on your server.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
Dim searcher As New ManagementObjectSearcher( _
"root\CIMV2", _
"SELECT * FROM Win32_ComputerSystem")
Dim en As ManagementObjectEnumerator = searcher.Get.GetEnumerator
MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
End Try
End Sub
I excluded some of the properties (as it would make the program too long) from the existing WMI class (Win32_ComputerSystem) to give you only the most important ones. The above program would list the server name, user logged in, DNSHostName, description (if any), whether it's part of a domain or not, the domain it belongs to, and finally the workgroup it belongs to. You can further extend the above program with several other properties available in the “Win32_ComputerSystem” class. You can even refer to MSDN online for further properties.
You can achieve the same thing with VBScript by using the following code:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
End Try
End Sub
I excluded some of the properties (because it would make the program too long) from the existing WMI class (Win32_UserAccount) to give you only the most important ones. The above program would list the full name, user name, domain the user belongs to and whether or not it is a local account. You can further extend the above program with several other properties available in the “Win32_UserAccount” class. You can even refer to MSDN online for further properties.
You can achieve the same result with VBScript by using the following code:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
The following VB.NET code would give you the information on all user groups available (whether or not the user group is part of a domain). It also includes user account information.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
Dim searcher As New ManagementObjectSearcher( _
"root\CIMV2", _
"SELECT * FROM Win32_AccountSID")
Dim dt As DataTable = globals.getStructure()
Dim en As ManagementObjectEnumerator = searcher.Get.GetEnumerator
While en.MoveNext
Dim queryObj As ManagementObject = en.Current
globals.addRow(dt, "User: ", queryObj("Element"))
End While
dt.AcceptChanges()
Me.DataGrid1.DataSource = dt
Catch err As ManagementException
MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
End Try
End Sub
You can achieve the same result by using VBScript code as follows:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_AccountSID",,48)
For Each objItem in colItems
Wscript.Echo "Element: " & objItem.Element
Next
One should note that I used different WMI classes and properties for different scenarios. You can get the full list of classes along with their properties and other documentation online at MSDN online. Hundreds of classes exist in WMI to fetch even the most in-depth information about your server.
Note that I am using “InvokeMethod” to execute a WMI method (in this case “Rename”) dynamically. “inParams” (an object of ManagementBaseObject) is specifically used to pass parameters to the WMI method “Rename”. It mainly contains the required information to penetrate through the authentication and authorization (username and password) of security, along with the new computer name. We can get the result after executing the WMI method “Rename” into “outParams”.
You can achieve the same result using the following VBScript code:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set objShare = objWMIService.Get("Win32_ComputerSystem.Name='SERVER'")
Set objInParam = objShare.Methods_("Rename").inParameters.SpawnInstance_()
You can further delve into the classes of WMI and design your own application to manage almost every important aspect of the Windows OS. If you extend your skills to ASP.NET, then you can develop a web application which can manage your server information on the fly, without your presence in the office itself! I think you can imagine the same, if you further extend it to the Pocket PC level! Good luck.
Anyway, once again, I must be thankful to all the readers who appreciated and encouraged me to further expand the series in a much more useful and efficient manner. Thank you very much.
Any comments, suggestions, bugs, errors, feedback etc. are highly appreciated at jag_chat@yahoo.com.