WMI Programming with Visual Basic.NET: Breaking the Ice

The goal of this series is to introduce Microsoft Windows Management Instrumentation (WMI) and get you up and running as quickly as possible, using it to manage your system through the WMI programming using .NET. In this article, we will cover the basics of WMI and how to access WMI information from Visual Basic.NET (both locally and remotely). Before diving into further details, we first need a little background in what WMI is, how it came about, and why it is valuable.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 18
June 21, 2005
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement


You can download a zip file of the entire Visual Studio.NET solution (developed for this article) here.

Introduction to WMI

Windows Management Instrumentation (WMI) is the Microsoft implementation of Web-based Enterprise Management (WBEM), an industry initiative to establish standards for accessing and sharing management information over an enterprise network. WMI is WBEM-compliant and provides integrated support for the Common Information Model (CIM), the data model that describes the objects that exist in a management environment.

WMI includes a CIM-compliant object repository, which is the database of object definitions, and the CIM Object Manager, which handles the collection and manipulation of objects in the repository and gathers information from WMI providers. WMI providers act as intermediaries between WMI and components of the operating system, applications, and other systems. For example, the registry provider draws information from the registry, while the SNMP provider provides data and events from SNMP devices. Providers give information about their components, and might provide methods to manipulate the components, properties that can be set, or events that can alert you to changes in the components.

The two paragraphs above are the definitions of WMI from Microsoft WMI team. But to put it simply, you can almost manage (or administrate) a single computer, an entire network, or even several domains with just WMI. The information you get from WMI can be further integrated with databases or the Web in an enterprise to work very efficiently, or remotely. To get the information from WMI, we need to use scripting (such as VBScript or Jscript) together with a huge repository of CIM. CIM contains all classes, objects or namespaces to the related resources (such as network, printer, and so forth).

Experts even suggest diverting to WMI rather than working on core WIN32 API. It is more difficult for a beginner to understand and work with WIN32 API than WMI. You can use WMI with programming (including .NET) or scripting systems (such as Windows Script Host) to retrieve configuration details about most aspects of your computer systems, including server applications, to make changes to your systems or even to schedule the scripts. We can also remotely administer the systems available in the network using WMI. And another wonder is that several tools from Microsoft are developed using WMI as the main technology. These tools include Microsoft Systems Management Server, Microsoft Operations Manager, and others.

What all of this means is that WMI makes Windows 2000/2003 extremely manageable by using a single consistent, standards-based, extensible and object-oriented interface. Also, any application or script accessing WMI data can do so on the local machine or remotely in a seamless way. And, it's not only for Windows 2000/2003; WMI is available for Windows 95, Windows 98, and Windows NT 4.0 as well (with a separate free download).

The above paragraphs just gave only a very basic introduction to WMI. Since this article (and series) mainly focuses on accessing WMI by using .NET, I request the readers to go through MSDN and WMI SDK for a complete architecture and explanation of how to use WMI.

Our first program to connect to WMI (on a local computer)

I just gave you a huge amount of theory without any practical examples. Now we shall create a simple windows application using Visual Basic.NET to get some information from WMI. Let's start by opening Visual Studio.NET 2003 Enterprise Architect.

  • After opening Visual Studio.NET 2003 IDE, go to File menu -> new -> Project.

  • Within the Visual Basic projects, select the "Windows Application" template (as shown in Fig. 1 below) and provide the name as "WMISample" at your own location and finally click OK.



    Figure 1
  • Drag a button and a listbox from the toolbox onto the form.

  • Name them as "btnShowDrives" and "lstDrives" respectively. The form should look like the one in Fig. 2 below.


    Figure 2
  • Go to Project menu -> Add Reference. Choose System.Management in the list of components (of .NET tab) and pressthe  "select" button. Finally click OK. You should be able to see System.Management as part of "references" in the solution explorer.

  • Modify your code so that it looks like the following:

    Imports System
    Imports System.Management

    Public Class Form1
    Inherits System.Windows.Forms.Form
    .
    .
    .

      Private Sub btnShowDrives_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShowDrives.Click
        'connect to "Win32_LogicalDisk" class of WMI
        Dim diskClass As New ManagementClass("Win32_LogicalDisk")
        'get the information
        Dim disks As ManagementObjectCollection = diskClass.GetInstances()
        'loop the information to store in an array
        Dim disk As ManagementObject
        Dim arDisks As New ArrayList
        For Each disk In disks
          arDisks.Add(disk("deviceid").ToString())
        Next disk
        'populate the listbox
        Me.lstDrives.Items.AddRange(arDisks.ToArray)
      End Sub
    End Class

  • Now, press F5 to execute the program. Click on the "Show Drives" button. And you should be able to see the listbox filled with all the drives attached (logically) to your computer (as in Fig.3).

Figure 3

Don't ignore the next section. It not only explains the above program, but also gives you a few tips on some interesting aspects.

Getting information from WMI

In order to get information (or data) from WMI, either on the local computer or from a remote computer, you must connect to the WMI service by connecting to a specific namespace. For example, the "root\cimv2" namespace (which is also the default) includes most of the classes that represent resources commonly associated with a computer and operating system. "root" is the main namespace to start with WMI. "cimv2" is a sub namespace available within the "root". There exist literally hundreds (or even thousands) of classes in the "root\cmv2" namespace. Similarly, there exist several other namespaces as well, logically grouped based on specific tasks.

The above paragraph provides you with just a procedure for working with WMI. But how do you implement it? The version of WMI that shipped with Windows 2000/2003 displayed classic COM interfaces to client applications. Therefore, you can access WMI-instrumented management data and events via the .NET COM Interop layer.

But there is a much better way to work with WMI from .NET. The System.Management namespace, defined as part of the .NET Framework, provides an easy-to-use, intuitive API for consuming WMI data and events. A lot of the complexities and idiosyncrasies of WMI APIs are taken care of by System.Management, and its class definitions follow the standard design paradigm of the .NET Framework.

Now, I would like to take a moment to explain the program in the previous section. Let us consider the following statement.

Imports System.Management

The above statement straight away imports all the necessary ingredients to work with WMI in our application. It must be added as a reference to our application before importing it.

Dim diskClass As New ManagementClass("Win32_LogicalDisk")

The above statement connects to a WMI class called "Win32_LogicalDisk". WMI creates a separate instance of this class for each and every logical drive present in the system. The class exists in "root\cimv2" namespace, which is the default namespace. You need not specify "root\cimv2" namespace, if you are working with any class within that namespace. If you really would like to do so, you need to change the above statement to something like the following:

Dim diskClass As New ManagementClass ("\\.\root\cimv2:Win32_LogicalDisk")

It is something like the UNC (Universal Naming Convention). The following gives you syntax for using the convention:

\\<ServerName>\root\<subnamespace>:<class>

Here is the next statement in the program:

Dim disks As ManagementObjectCollection = diskClass.GetInstances()

The above statement returns all the "instances" (or drives) of drives logically present in your system. Each drive returned (as part of the collection) is an "instance" of the class "Win32_LogicalDisk".

For Each disk In disks
  arDisks.Add(disk("deviceid").ToString())
Next disk

The above loop iterates through each instance of drives (present in the collection) and adds the "deviceid" to the arraylist. "deviceid" is a public member of the class "Win32_LogicalDisk". As we received the instances of the class "Win32_LogicalDisk" (from WMI), we are retrieving the value available in the "deviceid" member of each of those instances using a loop.

Me.lstDrives.Items.AddRange(arDisks.ToArray)

Finally, we add all the elements available in the arraylist to the listbox.

Our first program to connect to WMI (on a remote computer)

The previous sections introduced you to connecting only to a local computer, i.e. your own system. But what if I wanted to get the list of drives information for another computer (within the same network)? Is it as simple as changing the "ServerName" in the WMI path? Absolutely not.

When we try to get the information from another computer, the concept of security comes in. To connect to another computer within the network, we need to provide the authentication information along with the WMI path! The following shows you the necessary modifications for the above program to connect to another computer:

Dim options As New ConnectionOptions
options.Username = "administrator"
options.Password = ""
Dim scope As New ManagementScope("\\hostname\root\cimv2", options)
  Dim diskClass As New ManagementClass(scope, New ManagementPath("Win32_LogicalDisk"), Nothing)

Make sure you replace the "hostname" of the scope to the host name of the other computer within your network. So, the scope is now being provided with the necessary path, along with some connection options for username and password.

blog comments powered by Disqus
VISUAL BASIC.NET ARTICLES

- Basic Form Properties and Modality in VB.NET
- Multiple Document Interfaces in Visual Basic
- Visual Basic for Beginners
- ASP.NET Image to PDF with VB.Net
- MySQL in ASP.NET: Mono using VB.NET
- AsyncFileUpload File Type and File Size Vali...
- Visual Studio: Adding Functionality and Style
- Clocks and Countdowns
- User-defined Functions using Visual Basic Ap...
- Understanding Object Binding in VBA
- Mastering the Message Box
- Testing a Windows Forms Application
- Using Visual Basic.NET Features to Code a Wi...
- Correcting Code in a Windows Forms Applicati...
- Write Readable Code and Comments for Windows...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 6 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials