Passing info from PowerCLI into your VM using guestinfo variables

For a project at work we’ve been trying to pass information into a VM without connecting the VM to the network.
This is in order to set up some config within both Windows and Linux VMs. We decided to explore the use of GuestInfo variables which are held in memory in VMware Tools within the Guest VM, but which can be set from the host.

From the ESX Service Console of the host you can usevmware-cmd <cfgfile> setguestinfo <variable> <value> to set a value and vmware-cmd <cfgfile> getguestinfo <variable> to read the value. Note that you don’t need to use the “guestinfo.” prefix when using these commands.

Within the VM guest OS the values can be set/read using:(Windows)vmtoolsd.exe --cmd "info-set guestinfo.<variable> <value>"
vmtoolsd.exe --cmd "info-get guestinfo.<variable>"(vmtoolsd.exe is usually in C:\Program Files\VMware\VMware Tools)

It wasn’t immediately obvious where the guestinfo variables live with regard to the PowerCLI vmConfig properties. Googling didn’t reveal much useful info, so I though I’d try the wonders of new technology and use Twitter. I’ve been following Carter Shanklin of VMware on Twitter since I attended a London UK VMware User Group meeting a couple of months ago, and as he’s the Product Manager for PowerCLI and the SDK, I thought I’d ask.

He quickly pointed me at the VMware SDK documentation for the ConfigInfo object and the extraConfig object in particular.

A bit of further reading led me to some experiments let me to try the following code:$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$extra = New-Object VMware.Vim.optionvalue
$extra.Key="guestinfo.test"
$extra.Value="TestFromPCLI"
$vmConfigSpec.extraconfig += $extra
$vm = Get-View -ViewType VirtualMachine | where { $_.name -eq "MyVMName" }
$vm.ReconfigVM($vmConfigSpec)
That will set the guestinfo.test property to “TestFromPCLI”. Once that’s been set it can be read by the VM.

The guestinfo property can have multiple Key/Value pairs so you can pass quite a few variables through to a VM. These can only be set when a VM is powered up and running VMware Tools as the value is stored in the VMs memory, and as far as I can tell, the contents are lost when the VM reboots.

However, there is another extraConfig object which can also be set which is the machine.id. Again this can be read from within the VM (replace guestinfo. with machine.id in the above code snippets), but this one gets written to the VMs VMX config file and will thus survive reboots.

You could squish several bits of info into that one object/variable, for example a unique identifier and the VM name so that the VM can self-configure.

Just a general powershell tip, instead of using
$vm = Get-View -ViewType VirtualMachine | where { $_.name -eq “MyVMName” }
it is a lot quicker to use
$vm = Get-View -ViewType VirtualMachine -Filter @{“Name”=”MyVMName”}

The first row gets all servers and then displays the matchning server, if you have many servers this can take a long while.
The second row filters the request itself and only returns the matchning server resulting in a much faster code.
This is the same behaviour for all commands in PowerShell that supports the -Filter variable.