You are totally right, and I will live up to the title. Just bear with me, it will be worth it.
In November 2004 I got involved the first time with WMI by means of a question from a VBCitizen. He wanted to monitor printers on his network through WMI and was stuck in some code-logic. The code he showed on how he retrieved the remote printer information kind of sucked my eyes into the my monitor. The statement that got me going was:
moSearch = New Management.ManagementObjectSearcher("Select * from Win32_Printer")
Surely it could not be as simple as issuing one statement ? After a quick copy 'n' paste I ran his code on my machine, and lo and behold: all my logical installed printers got listed, fax and (installed shares to) remote printers included. I have to admit I felt euphoric as the realization of the new possibilities rushed through my veins. Anyway, his posting marked the start of my journey through the WMI. I started out to assist the VBCitizen, and in that process I've learned a lot about WMI in conjunction with VB.NET.
Are you still with me ? Good, then here is your reward for your perseverance:
The Connection Tester
One of the results of this journey is my VB.NET class 'ConnectionTester'. As the name implies, it was originally conceived as a quick means to see if a remote computer was on-line, as the WMI connect() statement can take up considerable time to decide that a remote is off-line or the remote RPC server is unavailable. I found a faster method in a DNS-query, which tells me if a computer is on-line in a matter of seconds.
The next step was to build in a check for WMI availability on the remote computer by initiating a WMI connection to the remote namespace and handle all possible exceptions thrown. Having finished testing the WMI check I realized that if remote WMI was available I had an open WMI connection to my disposal. Acknowledging the fact that closing an re-opening a WMI connection is a time-consuming and processor-intensive activity ( as with several other WMI functionalities, so be prepared to dig into threading to speed up or un-freeze your application..) I decided to extend my class to a light-weight WMI connection wrapper.
This wrapper-class consists of only two methods ( .Poll and .ExecWmiQuery), and properties that are divided into two types: those that are to be set before invoking .Poll, and those that get populated as a result of invoking .Poll.
Of the properties that are to be set, providing either the .ServerName or the .IPAddress is mandatory. The other properties (.WmiCheck, .WmiNameSpace, .UserName, .Password) are optional to provide some degree of flexibility
The results of a call to .Poll gets stored in the properties .IsOnline, .WmiEnabled, .HasErrors, .ErrorMessage, .PollInProgress, .OperatingSystem and .WmiScope
...So , Where Does the EASY Part Come In ?
Right here. Establishing a WMI connection to a remote computer now takes just three statements:
'* Create an instance of the ConnectionTester class
Dim myConn as New ConnectionTester
'* point to the computer to connect
MyConn.ServerName = "PC_admin"
'* Initiate connection
That's it. Gone are the ManagementScope, ConnectionOptions, ManagementObjectSearcher classes and low-level exception handling.
After a successful call to .Poll ( you can check that through the .IsOnline, .WmiEnabled and .HasErrors properties), you can take over the connection ( the .WmiScope property) to do your own stuff, or you could use the build-in query mechanism.
The next code block will list all processes running on the selected computer:
'* Create storage for the query result
Dim WmiQueryResult As System.Management.ManagementObjectCollection
'* Retrieve WMI-objects of processes running on target
WmiQueryResult = myConn.ExecWmiQuery("Select * From Win32_Process")
'* List returned process-names
Dim WmiObject as System.Management.ManagementObject
For Each WmiObject In WmiQueryResult