Windows Management Instrumentation is a well documented framework for network admins. There are hoards of management software suites that use it and can give you great stuff right out of the box. Some of it is great and some is not so good. One simple piece of information I wanted was, how much free space do my sql server drives have? I wanted it in a spreadsheet so I could sort and start examining the servers that were getting low on space. We utilize several monitoring and management tools but there didn’t seem to be a good solution.
I avoided some possibly important tasks and wrote my own solution using WMI. Querying WMI is rather simple. It is a lot like querying a sql database. Here is an example:
Select Label, Name, FreeSpace, Capacity from Win32_Volume where Label 'System Reserved' and DriveType 5
If you start a new VB.NET project the only trick is to add a reference to System.Management. The core piece of code in my project is a function that I pass the computer and query into and get a management object back.
Public Function QueryWMI(ByVal query As String, ByVal ComputerName As String) Dim wmiScope As New ManagementScope("\" & ComputerName & "\rootcimv2", New ConnectionOptions) Dim smoQuery As System.Management.ObjectQuery = New System.Management.ObjectQuery(query) Dim smoSearcher As ManagementObjectSearcher = New ManagementObjectSearcher(wmiScope, smoQuery) Return smoSearcher.Get() End Function
The next piece of code flips through the results. I chose to parse the results to a .csv file so I could simply double click and open in excel to do my slicing and dicing.
Function wmidrivefreespace(ByVal ComputerName As String) As String Dim retstr As String = "" For Each oReturn As ManagementObject In QueryWMI("select Label, Name, FreeSpace, Capacity from Win32_Volume where Label 'System Reserved' and DriveType 5", ComputerName) Try Dim label As Object = oReturn("Label") Dim name As Object = oReturn("Name") Dim freesp As Object = oReturn("FreeSpace") Dim cap As Object = oReturn("Capacity") If label = Nothing Then label = " " If name = Nothing Then name = " " If freesp = Nothing Then freesp = " " Else freesp = (Double.Parse(freesp) / 1024 / 1024 / 1024).ToString("N2") If cap = Nothing Then cap = " " Else cap = (Double.Parse(cap) / 1024 / 1024 / 1024).ToString("N2") retstr &= ComputerName & "," & label.ToString() & "," & name.ToString() & "," & freesp.ToString() & "," & cap.ToString() & System.Environment.NewLine Catch ex As Exception System.IO.File.AppendAllText(DateTime.Now.ToString("yyyyMMdd") & "errorlog.txt", ComputerName & ex.ToString & System.Environment.NewLine & System.Environment.NewLine) End Try Next Return retstr End Function
For this to work there is a WMI service on the target machine that has to be started (it is by default). Also, inbound port 135 has to be open on the target machine. If it isn’t already open on all of your computers I would be surprised since so many other things use WMI.
If you visit MSDN and check out the classes http://msdn.microsoft.com/en-us/library/aa394084(v=VS.85).aspx you might be shocked at how much information you can gather.
There is a bug in the above code that is easily fixed. If you spot it, post a comment. The hint is: Make sure to wash your punk.