Arnim van Lieshout Rotating Header Image

PowerCLI: Get WMI info from isolated guests

A few weeks back I posted an article on matching Windows and VMware disks. Unfortunately this would work only if you could remotely query WMI information from that VM. If you have any VM that’s isolated or behind a firewall, you are out of luck. This bothered me, so I started looking for a uniform method to retrieve WMI information. I already knew that it was possible to run PowerShell scripts inside a guest using the Invoke-VMScript cmdlet, but unfortunately I don’t have PowerShell installed in all my VMs yet. When reading through the change log of PowerCLI 4.0 Update 1, I noticed the following enhancement of the Invoke-VMScript cmdlet:

feature Enhanced Invoke-VMScript to support BAT (Windows) and BASH (Linux) scripts.

When it’s possible to run BATCH scripts inside a guest, it’s probably possible to run executables directly too. So I took this for a test and it turned out that it was working indeed. View the following piece of code to execute the “dir c:\” command inside a VM.

Connect-VIServer vmwsv392

$VM = Get-VM ( Read-Host "Enter VM name" )
$ESXHost = $VM | Get-VMHost

$HostCred = $Host.UI.PromptForCredential("Please enter credentials", "Enter ESX host credentials for $ESXHost", "root", "")
$GuestCred = $Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for $VM", "", "")

Invoke-VMScript "dir c:\" -vm $VM -HostCredential $HostCred -GuestCredential $GuestCred -ScriptType "bat"

When running this script on my environment, I receive a nice directory listing of the c: drive on that VM. Nice!

Let’s take this method one step further. As of Windows 2003 there’s a wmi command-line utility available to us called “wmic.exe”. After fiddling around with all the available options of this command, I figured out a way to get WMI info in csv format. The syntax I need to provide me that information is:

wmic path <WMI_class> get <property_list> /format:csv

For example I can retrieve a list of diskdrives and their sizes using:

wmic path win32_diskdrive get caption,deviceid,size /format:csv

The next challenge I faced, was the fact that the info is returned as a string. I needed a way to convert the string value to an array, preferably an array of objects. All I was looking for was the output of the Import-Csv cmdlet, but unfortunately this cmdlet doesn’t accept data on the pipe. The solution I found to this is rather simple, just dump the string value to an intermediate temporary file and import that file using Import-Csv.

To do this properly we first have to cut off the first 2 characters of the string (There’s an extra carriage return and line feed character at the beginning) or else we can’t import the file using Import-Csv, because it expects the header to be on the first line.

I’ve modified the previous example code a bit as shown below:

Connect-VIServer vCenterServer01

$VM = Get-VM ( Read-Host "Enter VM name" )
$ESXHost = $VM | Get-VMHost

$HostCred = $Host.UI.PromptForCredential("Please enter credentials", "Enter ESX host credentials for $ESXHost", "root", "")
$GuestCred = $Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for $VM", "", "")

$Out = Invoke-VMScript "wmic path win32_diskdrive get caption,deviceid,size /format:csv" -vm $VM -HostCredential $HostCred -GuestCredential $GuestCred -ScriptType "bat"

$FileName = [System.IO.Path]::GetTempFileName()
$Out.Substring(2) > $FileName
$In = Import-Csv $FileName
Remove-Item $FileName

When you look at the output window, you clearly see the differences between the $out and $in objects.

The converted $in object can easily be used inside PowerShell scripts.
Imagine the possibilities!

5 Comments on “PowerCLI: Get WMI info from isolated guests”

  1. #1 Alan Renouf
    on Jan 21st, 2010 at 10:11 am

    Ok, now that is very very cool, nice one Arnim

  2. #2 Arnim van Lieshout – PowerCLI: Get WMI info from isolated guests « powercli.co.uk
    on Jan 21st, 2010 at 11:54 pm
  3. #3 ben.neise.co.uk » Changing drive letter assignments after deploying a virtual machine from a template
    on Jan 22nd, 2010 at 2:36 pm

    [...] saw Arnim van Lieshout’s post on Invoke-VMScript yesterday, and realised that this could be used to run the DISKPART script on multiple machines. In order to [...]

  4. #4 dougie
    on Jan 22nd, 2010 at 6:38 pm

    nice script arnim

  5. #5 Jase's Place » Update VMware Windows Guest DNS and WINS through PowerCLI
    on Jan 22nd, 2010 at 9:05 pm

    [...] was really taken with Arnim Van Lieshout’s post on running getting WMI infor from inside a guest through the PowerCLI, so I decided to play around [...]

Leave a Comment