Set VMTools time synchronization mode on all VMs in a cluster

Standard

When changing the time synchronization settings in your environment you may have to also make modifications in your VMWare infrastructure. Among other things it can be necessary to control if the VM should synchronize its time from the host server or not. Normally it’s a manual process where you have to click into the VM settings and go to the Options tab and select VMWare Tools and there check the box or not. This script will do all that for you and set the VMTools host time synchronization to the value you choose, on all VMs in a given cluster. This will save you a lot of time especially if you, like me, manage a VMWare infrastructure with hundreds of VMs.
Although the script is quite short I have divided it into three sections variables, functions and script main to simplify its structure.

Variables

#VARIABLES
$DebugPreference = "continue" #comment out to disable debug info
#Parameters
$vcenter = "some_vcenter_server" #your vcenter server name
$clusterName = "Some_Cluster" #advanced settings will be set on all VMs on this cluster
$TimeSync = $true #script will enable/disable time sync on host on the VMs based on this value. Valid values are $true and $false

Before you run the script you will need to fill out the parameters in the variables section. $clustername is the name of the cluster on which you want to the change the settings for your VMs. All VMs running on the cluster will have their VMTools host time sync value set to what you specify in $TimeSync.

Functions

#FUNCTIONS
function ConnectToVcenter {
	param(
		$vcenter
	)
	#Load snap-in and connect to vCenter
	if (-not (Get-PSSnapin -Name VMware.VimAutomation.Core)) {
		Add-PSSnapin VMware.VimAutomation.Core
	}
	if ($global:DefaultVIServers.Count -lt 1) {
		Connect-VIServer $vCenter
	}
}
function Set-SyncValue {
	[CmdletBinding()]
	[OutputType([System.String])]
	param(
		[Parameter(ValueFromPipeline=$true)]$VM,
		[bool]$SyncValue
	)
	begin {
		Write-Debug "Creating configuration specification object"
		$ConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec 
		$ConfigSpec.tools = New-Object VMware.Vim.ToolsConfigInfo 
		$ConfigSpec.tools.syncTimeWithHost = $SyncValue
	}
	process {
		#configure the VM
		Write-Debug "Setting VMTools time sync to $SyncValue on $($VM.Name)"
		$View = get-view -viewtype virtualmachine -Filter @{'name'=$VM.Name} 
		$View.ReconfigVM_task($ConfigSpec)
		sleep 3 #wait for the configuration to complete
		#Check if the VM was configured as desired.
		$AfterView = get-view -viewtype virtualmachine -Filter @{'name'=$VM.Name} 
		[bool]$result = [System.Convert]::ToBoolean($AfterView.Config.Tools.syncTimeWithHost)		
		if ($result -eq $SyncValue) {
			Write-Debug "Successfully set the Tools.syncTimeWithHost on $VM to $SyncValue"
		}
		else {
			Write-Debug "Error - $VM - Couldn't set the Tools.syncTimeWithHost to the desired value of $SyncValue"
		}
	}
	end {
		Write-Debug "Finished setting time sync values on VMs."
	}
}

The script uses two functions which I will go over now.
1. Function ConnectToVcenter
This function takes one parameter $vcenter which is the name of the vcenter server. If not already done the function adds the VMWare snap-in for powershell and then connects to vcenter to make ready for the commands we will run after.
2. Function Set-SyncValue
Set-SyncValue takes two parameters $VM and $SyncValue. $VM can be passed from the pipeline which makes it easy to use in combination with other VMWare commands. The function works by first creating a configuration specification object with the value given in $SyncValue. After this it loops though the given VMs and reconfigures them accordingly. After the command to configure a VM has been sent, the script waits 3 seconds and then checks if the setting was updated to the value you wanted.

Script Main

#SCRIPT MAIN
ConnectToVcenter -vcenter $vcenter
Get-Cluster $clusterName | Get-VM | Set-SyncValue -SyncValue $TimeSync 

The script main is very short and simple. First I connect to vcenter using the function ConnectToVcenter. The actual work is then done in a one liner where I simply pipe all the VMs from the Get-Cluster and Get-VM cmdlets to the Set-SyncValue function.

That’s it. I hope you find the script useful. I have copied the full version of the script in below.

#####################################################################################################
##Script:			Set-VMTools_TimeSync.ps1
##
##Description:		enables/disables the VMTools time sync mode on all VMs in a given cluster.
##Created by:		Noam Wajnman
##Credits:			Part of this script was based on this article: 
#+					https://psvmware.wordpress.com/tag/disable-vmware-tools-time-sync-using-powercli/
##Creation Date:	April 28, 2014
#####################################################################################################
#VARIABLES
$DebugPreference = "continue" #comment out to disable debug info
#Parameters
$vcenter = "some_vcenter_server"
$clusterName = "Some_Cluster" #advanced settings will be set on all VMs on this cluster
$TimeSync = $true #script will enable/disable time sync on host on the VMs based on this value. Valid values are $true and $false
#FUNCTIONS
function ConnectToVcenter {
	param(
		$vcenter
	)
	#Load snap-in and connect to vCenter
	if (-not (Get-PSSnapin -Name VMware.VimAutomation.Core)) {
		Add-PSSnapin VMware.VimAutomation.Core
	}
	if ($global:DefaultVIServers.Count -lt 1) {
		Connect-VIServer $vCenter
	}
}
function Set-SyncValue {
	[CmdletBinding()]
	[OutputType([System.String])]
	param(
		[Parameter(ValueFromPipeline=$true)]$VM,
		[bool]$SyncValue
	)
	begin {
		Write-Debug "Creating configuration specification object"
		$ConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec 
		$ConfigSpec.tools = New-Object VMware.Vim.ToolsConfigInfo 
		$ConfigSpec.tools.syncTimeWithHost = $SyncValue
	}
	process {
		#configure the VM
		Write-Debug "Setting VMTools time sync to $SyncValue on $($VM.Name)"
		$View = get-view -viewtype virtualmachine -Filter @{'name'=$VM.Name} 
		$View.ReconfigVM_task($ConfigSpec)
		sleep 3 #wait for the configuration to complete
		#Check if the VM was configured as desired.
		$AfterView = get-view -viewtype virtualmachine -Filter @{'name'=$VM.Name} 
		[bool]$result = [System.Convert]::ToBoolean($AfterView.Config.Tools.syncTimeWithHost)		
		if ($result -eq $SyncValue) {
			Write-Debug "Successfully set the Tools.syncTimeWithHost on $VM to $SyncValue"
		}
		else {
			Write-Debug "Error - $VM - Couldn't set the Tools.syncTimeWithHost to the desired value of $SyncValue"
		}
	}
	end {
		Write-Debug "Finished setting time sync values on VMs."
	}
}
#SCRIPT MAIN
ConnectToVcenter -vcenter $vcenter
Get-Cluster $clusterName | Get-VM | Set-SyncValue -SyncValue $TimeSync
Advertisements

One thought on “Set VMTools time synchronization mode on all VMs in a cluster

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s