Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Framework  »  WMI connections made easy in VB.NET
WMI connections made easy in VB.NET
by Martin de Klerk | Published  04/24/2005 | .NET Framework | Rating:
Martin de Klerk

Born in 1958 and bitten by the computer-bug in 1976, I am an autodidact to the letter.

Through the years I have:
  - accumulated programming experience ranging from writing device-drivers to developing advanced MIS programs.
  - mastered languages like Assembler, C/C++/C#, (several flavours of) Basic, Cobol, Forth, Eiffel and Clipper
  - filled nearly every job/position the IT world has to offer as employee or contractor.
  - worked with customers ranging from your local grocery-shop, farmers, hospitals, offshore companies, governemental departments to multinationals like Shell, Afga-Gevaert, ABN/AMRO and Phillips N.V.

Currently I am:
  - running my own consultancy business since 1993.
  - developing 80% of my solutions in VB.NET
  - dividing my sparse moments of free time between my family, music (especially enjoy jamming with my son : on the guitar he's the gifted one, I just manage a bit of semi-decent guitar/harmonica play) and VBCity.
  - eagerly awaiting the official release of .NET Framework 2.0

 

View all articles by Martin de Klerk...
Introduction

This document is not intended as a WMI tutorial, and as such does not cover WMI itself. This document is about using WMI in VB.NET and is intended as a rough and practical (but by no means complete!) guide to get you up and running with WMI as a VB.NET programmer.

Without running into brick walls, that is. At least a lot less than I did. Windows Management Instrumentation can be a big PITA for the inexperienced. It's intricacies and (for instance) OS version dependencies are not for the fainthearted, but once you've got it going it offers tremendous possibilities.

I am a seasoned programmer and have programmed for various operating systems, but as a result of recently being exposed to the realm of WMI the number of gray hairs on my head has doubled. And to prevent all VB.NET programmers all over the world being recognizable by their excessive grey hairs or even their baldness, I offer you the benefits of my mistakes and experiences on this topic so that your VB.NET/WMI endeavours may be enjoyable.

Deciding I would stick to the (VB).NET paradigm I rejected scripting or WBEM as a means of accessing WMI, and concentrate on the System.Management namespace.

(Remote) connection to WMI Overview

Establishing a remote WMI connection involves several issues, varying from communication ports to authorization. If I was given a dollar for every time someone was confronted with the error message "Remote RPC-server not available" due to a port blocked by a firewall or an invalid DCOM/COM+ authentication, I'd probably end up in the Forbes Top 100.

As WMI uses several protocols and each protocol using its own pre-defined communication ports, firewall settings should allow access through the following ports for basic WMI operations:

      RPC   TCP 135,139,445,593
      SNMP   UDP 161,162
      Optional:
      WINS   TCP 42 UDP 42, 137
      PrintSpooler  TCP 139, 445
      TCP/IP PrintServer TCP 515

Note: there are more port settings involved for advanced features, but this will suffice for basic functionality. Also, make sure the DCOM/COM+ services are running all computers involved. Security in WMI is related to connecting to a namespace. WMI uses DCOM to handle remote calls. The most common reason for failure to connect to a remote computer is due to DCOM failure (error "DCOM Access Denied" decimal -2147024891 or hex 0x80070005). You can configure DCOM settings for WMI using DCOM Config in the Control Panel Administrative Tools. Here you can set the security to launch, access, and configure the WMI service.

The second pitfall is authorization: you must have admin rights on the (remote) computer.

The third pitfall is O.S. dependency. For instance, the DCOM/COM+ interface used by WMI requires different AuthenticationLevel settings depending on the OS: when connecting to systems running a MS Windows version prior to XP the AuthenticationLevel.Connect setting is mandatory to get access to the objects and classes interfaced through DCOM/COM+, but XP requires this setting to be AuthenticationLevel.Packet. Later on this OS dependency will also be an issue on the availability and/or functionality of several WMI classes and objects.

When the above conditions are met, you are connected to the (remote) WMI server. The next step is to connect to a WMI namespace. A WMI namespace contains WMI classes and objects, just like a .NET namespace, but it is also your 'workspace'. Best way to think of a WMI namespace is like a folder and its subfolder to which you have to log in.

Just as the .NET Framework, WMI provides several of those namespaces according to functionality. Currently the default WMI namespace = "\root\cimv2". By supplying the full path to the namespace you can connect to the local WMI namespace ("\.\root\cimv2") or to a remote namespace ("\pc_admin\root\cimv2")

Once connected to a the namespace, you have access to the classes and objects residing in that namespace.

What you need to code a WMI connection in VB.NET.

Enter System.Management.ConnectionOptions and System.Management.ManagementScope. Together they form the gateway to the WMI realm. You need the ConnectionsOptions object for authentication settings, and the ManagementScope class for the actual connection. All communications regarding WMI classes and objects will involve the latter class.

    Dim myConnectionOptions As New System.Management.ConnectionOptions
    With myConnectionOptions
        .Impersonation = System.Management.ImpersonationLevel.Impersonate
        '* Use next line for XP
        .Authentication = System.Management.AuthenticationLevel.Packet
        '* Use next line for Win prior XP
        '*.Authentication = System.Management.AuthenticationLevel.Connect
    End With

The above code will set the default authorization needed for a WMI connection. This object will, together with a fully qualified WMI namespace, form the means to establish a connection:

    Dim myManagementScope As System.Management.ManagementScope
    '* Replace the "." with an actual servername for remote connection
    Dim myServerName As String = "."
    myManagementScope = New System.Management.ManagementScope("\" & _
      myServerName & "\root\cimv2", myConnectionOptions)
    '* connect to WMI namespace
    myManagementScope.Connect()
    If myManagementScope.IsConnected = False Then
        ConsoleWriteLine("Could not connect to WMI namespace")
    End If

Beware that if the conditions do not conform as fore-mentioned in the previous paragraph '(Remote) connection to WMI Overview', your application will throw an exception on the statement myManagementScope.Connect().

Comments    Submit Comment

Comment #1  (Posted by an unknown user on 07/13/2005)
Rating
This article is great. Easy to read and understand. It gave me everything I needed.
 
Comment #2  (Posted by an unknown user on 07/22/2005)
Rating
This is a good starter. Luckily, you provide the links to the downloads at the end of the article. It's perhaps a good idea to provide them inside the text as well.
 
Comment #3  (Posted by an unknown user on 07/29/2005)
Rating
It is perfect
 
Comment #4  (Posted by an unknown user on 08/02/2005)
Rating
After days of crawling the net, this is the most professional article found yet on WMI & remote connectivity.

WELL DONE !
 
Comment #5  (Posted by an unknown user on 08/02/2005)
Rating
After days of crawling the net, this is the most professional article found yet on WMI & remote connectivity.

WELL DONE !
 
Comment #6  (Posted by an unknown user on 08/24/2005)
Rating
Great approach to introducing people to WMI. Simple to read and understand. Great Job.
 
Comment #7  (Posted by an unknown user on 09/01/2005)
Rating
Found exactly what I needed to fix my code. Thanks
 
Comment #8  (Posted by an unknown user on 10/06/2005)
Rating
This is a great job. In my case help me to resolve a problem with network server monitoring. Thanx for all.
 
Comment #9  (Posted by an unknown user on 10/17/2005)
Rating
Nice and simple.
 
Comment #10  (Posted by an unknown user on 11/12/2005)
Rating
Impeccably presented.
 
Comment #11  (Posted by an unknown user on 12/01/2005)
Rating
It is what I need to use WMI. And the links is useful for me
 
Comment #12  (Posted by an unknown user on 12/02/2005)
Rating
Excellent article. Very well written.
 
Comment #13  (Posted by Andy Bonner (aka Skullcrusher) on 12/04/2005)
Rating
Just found another port that needed to be allowed on XP SP2.

TCP Port 1038 - Message Tracking Query Protocol
 
Comment #14  (Posted by Benjamin Lindelof on 12/09/2005)
Rating
Unable to follow the author.
 
Comment #15  (Posted by an unknown user on 12/09/2005)
Rating
No method to read the Arrays in WMI?
 
Comment #16  (Posted by an unknown user on 12/09/2005)
Rating
No method to read the Arrays in WMI?
 
Comment #17  (Posted by Benjamin Lindelof on 12/09/2005)
Rating
I found the bug. Instead of:
myManagementScope = New System.Management.ManagementScope("\" & _
It should say:
myManagementScope = New System.Management.ManagementScope("\\" & _

 
Comment #18  (Posted by an unknown user on 12/12/2005)
Rating
The article is very good. However, I can't figure out how to download the code. I have searched the following page and can't find the word "download" or anything tat looks like a download link for the ConnectionTester referenced on page 5 of the article:

http://www.devcity.net/Articles/144/6/article.aspx

Thanks!
 
Comment #19  (Posted by an unknown user on 12/12/2005)
Rating
The article is very good. However, I can't figure out how to download the code. I have searched the following page and can't find the word "download" or anything tat looks like a download link for the ConnectionTester referenced on page 5 of the article:

http://www.devcity.net/Articles/144/6/article.aspx

Thanks!
 
Comment #20  (Posted by an unknown user on 12/25/2005)
Rating
Many thanks, you saved me a lot of time (and maybe grey hairs ^^)!
 
Comment #21  (Posted by an unknown user on 12/25/2005)
Rating
To look at additional WMI classes, see the wbemtest.exe tool located on any system with WMI installed. Just goto Start --> Run, then type "wbemtest", then connect to the "root\cimv2" (or a different) namespace, click Enum Classes --> Recursive!
 
Comment #22  (Posted by Bhaskar on 01/20/2006)
Rating
Thanks for the fruitful efforts made !

This code works very well when the servername/IP Address is "localhost"/127.0.0.1

When i give Servername as one of the systems in the LAN it gives:
"Connecting to {0}DevServer{0}DevServer is online with IP address: {1}192.168.1.25.Error while connecting to {0}DevServer: {1}Access denied"

This is the case with all the systems in my LAN.
Please help!!!
 
Comment #23  (Posted by an unknown user on 01/21/2006)
Rating
Either I am blind or there is no link to download this code. I am exited about it, but am also frustrated that I cannot download it :(
 
Comment #24  (Posted by Kevin on 01/29/2006)
Rating
Why is there no remoting example using early binding. All that is said is that mgmtclassgen.exe can be used to make WMI strongly typed.
 
Comment #25  (Posted by an unknown user on 02/02/2006)
Rating
great
 
Comment #26  (Posted by an unknown user on 02/11/2006)
Rating
Well, I was looking for this information and, wow, I found much more than I expected. Great job! Hopefully your grey hair turn back! ;)
 
Comment #27  (Posted by an unknown user on 03/09/2006)
Rating
just easy too read - keep on goin'
 
Comment #28  (Posted by an unknown user on 03/09/2006)
Rating
Excellent tutorial! The download is difficult to find, but not the authors fault. Works great. There is one mistake in the first page example as mentioned already, missing a \. Should be \\. Anyway, great stuff, the class is awesome!
 
Comment #29  (Posted by an unknown user on 03/13/2006)
Rating
I find this article easy to understand, it's perfect for a beginner like me searching to get the best from WMI
 
Comment #30  (Posted by an unknown user on 03/31/2006)
Rating
Felicitaciones.
Es un articulo facil de entender para los desarrolladores de otros idiomas.

Deben cambiar el link de:

WMI Administrative Tools (including CIM studio)

a:


http://www.microsoft.com/downloads/details.aspx?FamilyID=6430f853-1120-48db-8cc5-f2abdc3ed314&DisplayLang=en

Oscar José Lofrano Maturi
ojlofranom@msn.com
MCP VB.NET Windows Application
Venezuela
 
Comment #31  (Posted by Someone on 04/18/2006)
Rating
Great article! But there is a bug in the function ExecWmiQuery ;) It does not work for a remote Win2003 machine that requires login. Instead of

_ManagementSearcher = New System.Management.ManagementObjectSearcher(_ManagementScope.Path.ToString, cWmiQuery) ' bug: this will cause a new ManagementScope object to be created, when the correct ManagementScope object already exists

Use:

Dim query As New ObjectQuery(cWmiQuery)
_ManagementSearcher = New System.Management.ManagementObjectSearcher(_ManagementScope, query)

Your code creates a new instance of ManagementScope and does not set the UserName and Password connection options. Instead use the existing _ManagementScope variable which does have the username and password set already! :)

 
Comment #32  (Posted by an unknown user on 04/20/2006)
Rating
A superb article to newbies of WMI like me but i want more info for remote connections,that code wont work in XP Machines and Server 2003
 
Comment #33  (Posted by an unknown user on 05/09/2006)
Rating
interesting
 
Comment #34  (Posted by Stuart Nathan on 06/27/2006)
Rating
When I run your example, I get the error message "RPC Server is unavailable" when I try to connect to another machine.
 
Comment #35  (Posted by an unknown user on 06/30/2006)
Rating
Very interesting article about the link between scripting & vb.net.Tnx!
 
Comment #36  (Posted by an unknown user on 07/06/2006)
Rating
Excelentemente explicado. De mucha utilidad y muy claro.
 
Comment #37  (Posted by an unknown user on 07/23/2006)
Rating
Very well written article. Easy to follow and informative. Thank you.
 
Comment #38  (Posted by an unknown user on 07/26/2006)
Rating
Easy to read, easy to understand.
Great article for someone starting out!
 
Comment #39  (Posted by sovannborith on 08/17/2006)
Rating
my computer does not have system.Management namespace. how can i get it. please reply

 
Comment #40  (Posted by an unknown user on 08/19/2006)
Rating
Breath of fresh air on the subject. I only wish that my web searches hit on the article sooner.
 
Comment #41  (Posted by an unknown user on 10/05/2006)
Rating
Great Job!! Thanks a lot
 
Comment #42  (Posted by Muhammad Aamir Hassan on 10/11/2006)
Rating
i really enjoyed this snipt. May God help you

aamir
 
Comment #43  (Posted by Lesh Augustus on 11/02/2006)
Rating
Set System Information or Set System Environment Variable in VB.Net
===================================================

Dim objEv As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT * FROM Win32_Environment")
For Each objMgmt As ManagementObject In objEv.Get
If objMgmt("Name") = "Path" And objMgmt("UserName") = "" Then
Dim strPath As String = objMgmt("VariableValue")
If strPath.ToLower.IndexOf("cvsnt") >= 0 Then
If objMgmt("VariableValue").ToString.Substring(objMgmt("VariableValue").ToString.Length - 1) = ";" Then
objMgmt("VariableValue") = objMgmt("VariableValue") + Trim(txtNewPath.Text) + ";"
Else
objMgmt("VariableValue") = objMgmt("VariableValue") + ";" + Trim(txtNewPath.Text) + ";"
End If
End If
objMgmt.Put()
MessageBox.Show("Path Added Successfully")
End If
Next
 
Comment #44  (Posted by PK on 12/22/2006)
Rating
Hi, I couldn't find the link to the ConnectionTester class?
 
Comment #45  (Posted by an unknown user on 03/12/2007)
Rating
Thanks buddy, very good article
 
Comment #46  (Posted by zmrcic on 03/14/2007)
Rating
I'm using wmi and I think its great article. I have new problem. Can I look into printer setup (emulation, characteset....) by wmi?
 
Comment #47  (Posted by an unknown user on 05/25/2007)
Rating
Hi Mr. Martin

Great article! But could you help me with the Access is Denied error? i'm trying to connect to a remote computer and it returns an online status but i can't access it. I think it's the rpc or something. AT CheckForWMI procedure, the error is in the else statement of the code below.

Catch e1 As Exception
'* USUALLY indicates remote RPC server is not online
If e1.Message.IndexOf("RPC-server") <> -1 Then
'* Do not set _HasErrors in this case
'* as that could be interpreted as being off-line
_ErrorMessage = e1.Message
Else
_HasErrors = True
_ErrorMessage = e1.Message
End If

i really need help please!
thanks!!
 
Comment #48  (Posted by Ashu on 10/09/2007)
Rating
Thank you very much for this article, WMI isn't exactly simple to access outside of say VBSCripting realm. :)

Anyway, I am not able to get the ConnectionTesterClass to work for some reason, I am using VB.NET 2005 Express edition and it says the System.Net has been obsolete...any idea how i Can go about resolving this?

Thanks again!
 
Comment #49  (Posted by Amit Ashok Pawar. on 12/17/2007)
Rating
Artical was nice. I got help from this artical. but your code is constantly giving me an error like Access is Denied. I'm using XP Service pack 2 (Professonal)Please help me.
 
Comment #50  (Posted by an unknown user on 02/10/2008)
Rating
Excellent Article. Thank you for writing this up.

I did find a problem though. The Win32_Product class has a prblem on Windows Vista. It's scheduled to be fixed in SP1.

On another note, I parsed all of the errors in the event log in the last 15 days. The date/time WMI returns is UGLY (20080210185042.0000000-000). I wrote it out with following lines of code:

Console.WriteLine("Date: {0}", Left(mo.GetPropertyValue("TimeGenerated").ToString, 4) & _
"-" & Mid(mo.GetPropertyValue("TimeGenerated").ToString, 5, 2) & _
"-" & Mid(mo.GetPropertyValue("TimeGenerated").ToString, 7, 2))
Console.WriteLine("Time (GMT): {0}", Mid(mo.GetPropertyValue("TimeGenerated").ToString, 9, 2) & _
":" & Mid(mo.GetPropertyValue("TimeGenerated").ToString, 11, 2) & _
":" & Mid(mo.GetPropertyValue("TimeGenerated").ToString, 13, 2))

DO you know if there's an easier way to reformat the date/time?

Thanks again for the article. It's exactly what I was looking for.
 
Comment #51  (Posted by an unknown user on 02/10/2008)
Rating
I found the answer (well, I posted and someone answered). Here's what I got:

Dim myDateTime As DateTime

myDateTime = System.Management.ManagementDateTimeConverter.ToDateTime(mo.GetPropertyValue("TimeGenerated").ToString)
Console.WriteLine(myDateTime)

Thanks to the guys over at asp.net (I posted in the wrong forum at the wrong site and still got the answer. That's the flexibility of the .Net framework for you.)
 
Comment #52  (Posted by Ron Mittelman on 02/20/2008)
Rating
What a great article!! I wrote a utility to monitor many server processes and services, and this made the job MUCH easier! Cudos.

Major problem:
Can't seem to connect to a new server, running Windows 2003 Server SP1. when executing this code:

Public Function ExecWmiQuery(ByVal cWmiQuery As String) As System.Management.ManagementObjectCollection

'* Coordinates simple WSL queries with the other end of the connection
_ManagementObjectCollection = Nothing
Try
Dim objQuery As ObjectQuery = New ObjectQuery
objQuery.QueryString = cWmiQuery
_ManagementSearcher = New ManagementObjectSearcher(_ManagementScope, objQuery)
'_ManagementSearcher = New System.Management.ManagementObjectSearcher(_ManagementScope.Path.ToString, cWmiQuery)
_ManagementObjectCollection = _ManagementSearcher.Get()


I get this error on the .Get statement:
Run-time exception thrown : System.UnauthorizedAccessException - Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

The actual query being attempted is simply:
"Select * From Win32_OperatingSystem"

I have connected with credentials having admin rights on the server. I can DameWare to the server and log on fine using these credentials. I have checked all DCOMConfig properties for WMI and they seem to allow local admins to do everything needed.

This is first time trying your class on a Win 2003 server. Could it be an OS issue, or a configuration issue?

Help!!!!
 
Comment #53  (Posted by an unknown user on 04/07/2008)
Rating
Funny, useful and clearly explained
 
Comment #54  (Posted by Miles Wade on 06/13/2008)
Rating
Very good article. Just enough information without overloading the reader. Thanks
 
Comment #55  (Posted by dwayne on 07/21/2008)
Rating
Simple to read and comprehensive, thank you so much for sharing this
 
Comment #56  (Posted by an unknown user on 09/02/2008)
Rating
You helpe me alot
Thanks for sharing information, but where is the code ?
 
Comment #57  (Posted by an unknown user on 09/06/2008)
Rating
Thanx! This is what I have been looking for. Thanx
 
Comment #58  (Posted by an unknown user on 10/22/2008)
Rating
it's good thanx
 
Comment #59  (Posted by an unknown user on 11/06/2008)
Rating
really great!!
Easy to understand :)
 
Comment #60  (Posted by an unknown user on 12/01/2008)
Rating
trocdo
 
Comment #61  (Posted by Hwj on 03/10/2009)
Rating
Where can I find the ConnectionTester class?
 
Sponsored Links