Using PowerCLI to Auto-Update VMWare Tools

If you’ve ever read my blog you already know I like to ramble, so if you’d like to get to the nitty gritty of this script, skip down to the “Rubber, meet Road” section.

First of all, excuse my ‘noobness’ as I recently started supporting a VMWare server cluster, and sometimes those of us that just start working with a proven technology, find things and go… “Holy Crap! You can do that?” A while ago, we upgraded our VCenter to version 4.something-or-other. After that upgrade, you have to upgrade the VMWare Tools. Well, while I was attending one of the local VMUG meetings, someone mentioned that you can do the upgrade and suppress the reboot via command line. So, once I got back to the shop, I used this simple command:

Get-VM vmname | Update-Tools –NoReboot

That was handy. All guests upgraded, no reboots, upgrade will complete during reboot of next patching cycle. Marvelous! Then, later I was digging around and found this setting:

I said to myself…. you guessed it, “Holy Crap! You can do that?” So, I started flipping through all of our Windows guests and turning that on, making it so I didn’t have to worry about it ever again. Then came the arrival of VCenter 5.0. We diligently upgraded our VCenter and hosts shortly before a patch cycle. After the patch cycle, all of my servers were still reporting that their VMware tools were out of date. Scratching my head, I double checked, and the previous settings for the auto-update during power cycle had been reset to default which is unchecked. UGH! The first time around, I thought I’d only have to do it once, so I changed the setting manually for my 100+ servers. This time, I decided to write a script, especially since the upgrade had changed my settings back to default, so there was a good chance this would happen again. Not only that, I can set this script to run automatically before each patch cycle so any new VMs will get set as well.

Of course, I started out with our friend Google. I found a pretty darn good post by Damian Karlson where I got most of my script and a few other links from that page for some more information. What I didn’t find was a “Here is what you have to know if you’re a noob” post, so I had to do some figuring out on my own.

Rubber, meet Road

First of all, I use PowerGUI Pro Script Editor from Quest Software for all of my scripting needs. I highly recommend it. You also have to make sure you have VMware Vsphere PowerCLI installed on the workstation that you’re running the script on. Also, make sure you have the PowerCLI libraries loaded. Secondly, you have to run your PowerCLI commands with appropriate rights. Check out my post on how to do that for programs by default (especially if you have a different account for admin rights). Thirdly, you have to connect to a server, which Damian’s post completely skips, because he and his readers know what they’re doing, unlike me. Finally, I had the challenge of having a large number of *nix systems that I have to skip since *nix admins are all picky about their software….. so, Damian’s original script just goes out, finds all VMs, and changes the setting. Mine needed to be a bit pickier. One of the comments in Damian’s post had a check in there to give me the command to single out Windows guests, so I put it all together, and this is what I got:

First connect PowerCLI to your VCenter server with this command:

Connect-VIServer -Server 10.10.10.10

Where, 10.10.10.10 is the IP of your VCenter server. You can connect to each host individually I believe, but if you have more than one host that doesn’t make sense if you have VCenter. This will prompt you for credentials, unless you launched the PowerShell instance with the user with appropriate permissions, then it will just connect you:

Name        Port User
—-        —- —-
10.10.10.10 443  DOMAIN\user

You could get a warning about an invalid certificate, a lot like you do when you connect with VSphere Client for the first time. You can turn off that warning with this command:

Set-powercliconfiguration -InvalidCertificateAction Ignore

Here is the script that I ran to change the setting on all of my Windows Guests:

Get-VM | Get-View | ForEach-Object{
Write-Output $_.name

if ($_.config.tools.toolsUpgradePolicy -ne “upgradeAtPowerCycle” -and $_.Guest.GuestFamily -match “windowsGuest”){
$vm = Get-VM -Name $_.name
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.changeVersion = $vm.ExtensionData.Config.ChangeVersion

$spec.tools = New-Object VMware.Vim.ToolsConfigInfo

$spec.tools.toolsUpgradePolicy = “upgradeAtPowerCycle”
$_this = Get-View -Id $vm.Id 
$_this.ReconfigVM_Task($spec)

Write-Output “Completed”
}
}

The only real difference between this script and the one Damian wrote is that mine will check if the Upgrade at Power Cycle flag is not already enabled, and then check if it is a Windows guest. If both conditions are true, then it will change the setting to “Upgrade at power cycle”. I referenced this post that discusses PowerShell’s If AND statements to refine line 3 of the script above.

Thanks to Damian and the comment made by Travis that got me 99% of the way to my solution.

Advertisements