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().

Sponsored Links