WMI and PowerShell v4 a match made in heaven

Natively Windows has a tool to access and view the WMI Namespaces, called WBEMtest.exe. In my opinion it can be quite clunky to use, especially when you are starting to learn WMI. There are multiple WMI Explorer’s out there that do a much better job of presenting the NameSpaces, Classes, Properties & Methods (personally, I use WMI Explorer from Sapien).

Another option is to use Window’s PowerShell to access the WMI objects.

You ask, why would I move from a GUI to a CLI for something like this? Answer: Because it is quicker, especially if it is something you query, quite often you can just simply save the query. It’s hard to save where you need to go in a GUI.

For this blog I’m going to discuss the 2 primary PowerShell cmdlets for WMI which are Get-WmiObject and Invoke-WmiMethod.

Get-WmiObject is used to get a WMIObject be it a NameSpace or a Class. You can also run a WQL Query using this same CmdLet.

An example would be Get-WmiObject -Class win32_bios which will return the following:

Again I hear well that’s great Steve you know to get that information you need to grab the win32_bios class, how the heck do I find what I’m looking for in PowerShell?

Well since PowerShell 3.0 there is a great parameter added to the Out-GridView cmdlet called PassThru. What this allows us to do is select the result we want from the gridview, and do something with it. As a script you could do something like this;

$wmi = Get-WmiObject -List | Out-GridView -passthru
Get-WmiObject -Class $wmi.Name 

 When we run the Script a box will appear like below, in the filter box you can treat this like a search;

When we search for Bios the list will be filtered down to only objects which contain BIOS, we can then select Win32_bios and click ok which places the whole Win32_BIOS object as $WMI;

And the final line is to get the WMI object we have selected;

Invoke-WmiMethod is used to invoke a method that is attached to a Class or Namespace, this one has a little bit more of a niche use case, but is very powerful.

For example we can use the following line to start an application like WBEMTest.exe;

Invoke-WmiMethod -class win32_process -name create -ArgumentList “wbemtest.exe”

As you can see WBEMTest will then appear on the screen.

You can find methods out the same way as you find classes with the following line of code;

$wmi = Get-WmiObject -List | Out-GridView -passthru
Get-WmiObject -Class $wmi.Name | Get-Member -MemberType Methods

 

So the same box as earlier will appear when we run the above lines;


In this example we have searched for Win32_process as it has Methods attached as you can see in the list

Once you select win32_process and Ok you will get the below results.

Ok so we have now used the Get-WmiObject and Invoke-WmiMethod
commandlets separately, let’s join them together and show how there is 2 ways to invoke the methods.

So in this example we are going to start WBEMTest.exe again and then close it by using the Win32_process Methods, the script looks like this;

$wbem = Invoke-WmiMethod -class win32_process -name create -ArgumentList
“wbemtest.exe”
$procid = $wbem.ProcessID
$res = Get-WmiObject -Query “Select * from win32_process where ProcessID = $procid
$res
$res.Terminate() 

 

So as you can see we are defining $wbem
with the result of Invoke-WmiMethod
which is creating a process for WBEMTest.exe, this allows us to capture the ProcessID which we then define as $procid on the next line.

From here we are querying the WMIObject Win32_Process where ProcessID = $procid, which will return the results of the process we just created into the $res variable.

We then return the $res
variable onto the screen to show that the script is doing something.

And the last line we actually close the WBEMtext.exe process we created in the first line. Which as you can see from the list of methods for Win32_process Terminate exists there.

Good Luck

Steve