You are on page 1of 7

Listing/Modifying Server Information with

Visual Basic.NET and VBScript Using WMI


(Page 1 of 5 )

This article explains how you can retrieve Windows server information using both Visual
Basic.NET and VBScript, along with WMI.

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)
Dim dr 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)
Dim dr As DataRow
dr = dt.NewRow
dr("FullName") = FullName
dr("Name") = Name
dr("Domain") = Domain
dr("LocalAccount") = LocalAccount
dt.Rows.Add(dr)
End Sub

Listing/Modifying Server Information with


Visual Basic.NET and VBScript Using WMI -
Listing minimum server information using
WMI
(Page 2 of 5 )

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
If en.MoveNext Then
Dim queryObj As ManagementObject = en.Current
Dim dt As DataTable = globals.getStructure()
globals.addRow(dt, "Caption", queryObj
("Caption"))
globals.addRow(dt, "Name", queryObj("Name"))
globals.addRow(dt, "UserName", queryObj
("UserName"))
globals.addRow(dt, "DNSHostName", queryObj
("DNSHostName"))
globals.addRow(dt, "Description", queryObj
("Description"))
globals.addRow(dt, "PartOfDomain", queryObj
("PartOfDomain"))
globals.addRow(dt, "Domain", queryObj("Domain"))
globals.addRow(dt, "Workgroup", queryObj
("Workgroup"))
dt.AcceptChanges()
Me.DataGrid1.DataSource = dt
End If

Catch err As ManagementException


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")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_ComputerSystem",,48)
For Each objItem in colItems
Wscript.Echo "Caption: " & objItem.Caption
Wscript.Echo "Name: " & objItem.Name
Wscript.Echo "UserName: " & objItem.UserName
Wscript.Echo "DNSHostName: " & objItem.DNSHostName
Wscript.Echo "Description: " & objItem.Description
Wscript.Echo "PartOfDomain: " & objItem.PartOfDomain
Wscript.Echo "Domain: " & objItem.Domain
Wscript.Echo "Workgroup: " & objItem.Workgroup
Next

Listing/Modifying Server Information with


Visual Basic.NET and VBScript Using WMI -
How to retrieve all user account information
using WMI
(Page 3 of 5 )

How can we list all the user accounts on your server? The following VB.NET code would
achieve this result.
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_UserAccount")
Dim dt As DataTable = globals.getUserAccountStructure
()
Dim en As ManagementObjectEnumerator =
searcher.Get.GetEnumerator
While en.MoveNext
Dim queryObj As ManagementObject = en.Current
globals.addUserAccountRow(dt, queryObj
("FullName"), queryObj("Name"), queryObj("Domain"), queryObj
("LocalAccount"))
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
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")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_UserAccount",,48)
For Each objItem in colItems
Wscript.Echo "FullName: " & objItem.FullName
Wscript.Echo "Name: " & objItem.Name
Wscript.Echo "Domain: " & objItem.Domain
Wscript.Echo "LocalAccount: " & objItem.LocalAccount
Next

Listing/Modifying Server Information with


Visual Basic.NET and VBScript Using WMI -
How to retrieve all group information along
with account information using WMI
(Page 4 of 5 )

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.

Listing/Modifying Server Information with


Visual Basic.NET and VBScript Using WMI -
How to change your computer name using
WMI
(Page 5 of 5 )

You can change your computer name using VB.NET and WMI as shown in the following:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
Try
Dim classInstance As New ManagementObject( _
"root\CIMV2", _
"Win32_ComputerSystem.Name='SERVER'", _
Nothing)
Dim inParams As ManagementBaseObject = _
classInstance.GetMethodParameters("Rename")
inParams("Name") = "server2" 'rename to
inParams("Password") = "admin"
inParams("UserName") = "administrator"
Dim outParams As ManagementBaseObject = _
classInstance.InvokeMethod("Rename", inParams,
Nothing)
MessageBox.Show("ReturnValue: {0}", outParams
("ReturnValue"))
Catch err As ManagementException
MessageBox.Show("Error: " & err.Message)
End Try
End Sub
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_()
objInParam.Properties_.Item("Name") = "server2"
objInParam.Properties_.Item("Password") = "admin"
objInParam.Properties_.Item("UserName") = "administrator"
Set objOutParams =
objWMIService.ExecMethod("Win32_ComputerSystem.Name='SERVER'", "Rename",
objInParam)
Wscript.echo "ReturnValue: " & objOutParams.ReturnValue
Summary
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.

You might also like