Enabling Bulk Check for VMWare Tools Upgrade

I have a pretty large virtual environment at work to the tune of 1600 VMs, 19 hosts, 5 clusters, 46 networks, and 67 datastores. In two weeks, I have to power everything down (boo!) because our building is doing maintenance on the power circuits on the building (yay!). To that end, I have noticed that a lot of my VMs have out of date VMWare Tools because they don’t have the option set to check for/install updated tools on reboot. I don’t particularly want to handle enabling these via GUI (as it would take forever) so I did some digging. I found a few scripts that do the trick but they don’t really have any logic in them – they merely set the option on every VM. Well, I would rather have the script check each VM beforehand to see what it’s setting is before making a change. So, I started modifying.

Some notes before beginning and if you use this code: it’s simply a PowerShell script. Create a text file somewhere handy, paste this code in, and save it with a .ps1 file extension. From vSphere PowerCLI, you’ll have to point it at a vCenter server (even if running on vCenter) with the command ‘Connect-VIServer *enter your server name here*’. Then, browse for the .ps1 file and execute it with ./filename.ps1.

To get started, I logged onto my Virtual Center server. For the record, it is running vSphere 5.1 Update 2. I launched vSphere PowerCLI and started playing around with commands. I stole most of this and added some modifications to prompt the user for the cluster name rather than running on all VMs (thanks to Damian Karlson) and came up with the following:

$cluster = Read-Host 'Enter cluster name'
$machines = Get-Cluster $cluster | Get-VM | Get-View | ForEach-Object{
Write-Output $_.name
if ($_.config.tools.toolsUpgradePolicy -ne “upgradeAtPowerCycle”){
$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”
}
}

Ok, neat. This prompts the user for a cluster name, queries vCenter for that cluster, queries the cluster for VMs, then churns through each VM, modifying them to enable the ‘upgradeAtPowerCycle’ option. Voila! But, I want it to do more, have more logic, let users choose if they want to run on a Datacenter, Cluster, Host, or VM level, and then execute based on that decision and the object name given.

**Edit 4/3/2014 4:46pm**
Ok, so I added some logic to let the user choose if they want to run against a datacenter or a cluster and then prompts for the name and runs:

$type = Read-Host 'Datacenter or Cluster?'

if ($type -eq "datacenter") {
$datacenter = Read-Host 'Enter Datacenter Name'
$datacenter = Get-Datacenter $datacenter

$machines = Get-Datacenter $datacenter | Get-VM | Get-View | ForEach-Object{
Write-Output $_.name
if ($_.config.tools.toolsUpgradePolicy -ne “upgradeAtPowerCycle”){

$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”
}
}
}

elseif ($type -eq "cluster") {
$cluster = Read-Host 'Enter cluster name'
$cluster = Get-Cluster $cluster

$machines = Get-Cluster $cluster | Get-VM | Get-View | ForEach-Object{
Write-Output $_.name
if ($_.config.tools.toolsUpgradePolicy -ne “upgradeAtPowerCycle”){

$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”
}
}
}

else{
}

**Edit 4/3/2014 5:35pm**

Consolidated code and added some verbosity. The script will display the VM name of any machines modified and state ‘Completed’ when done.

$type = Read-Host '(D)atacenter or (C)luster?'

if ($type -eq "datacenter" -or $type -eq "d") {
$datacenter = Read-Host 'Enter Datacenter Name'
$typevar = Get-Datacenter $datacenter
}

elseif ($type -eq "cluster" -or $type -eq "c") {
$cluster = Read-Host 'Enter Cluster name'
$typevar = Get-Cluster $cluster
}

else{
}

$typevar | Get-VM | Get-View | ForEach-Object{

if ($_.config.tools.toolsUpgradePolicy -ne “upgradeAtPowerCycle”){

Write-Host $_.name

$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-Host “Completed”

Comments

comments

Leave a Reply