Set VMware Snapshot Location with Powershell

Snapshots are m*th3rfcukers. If you’re not careful, they will mass-murder your vms. Yet they allow you to time-travel! You want to use them, but how to prevent a massacre? Here’s how: relocate the delta files.

When you create a snapshot, the current state of the vm is preserved by leaving the disk files alone. All changes since the moment of creating the snapshot are written to delta files. The delta files are stored in the vm’s working directory. The working directory is – by default – the location where the vmx and other config files reside. If that datastore runs out of free space – especially if it also contains disk files – you’re in a bit of a kerfuffle. Vms not booting or being frozen as if they stared into Medusa’s reptoid eyes.

So you can do two things: reserve overhead in your datastores and stay afraid some overactive snapshot might destroy your environment, or set the working directory of your vms to some big-ass datastore you don’t use for anything else and let the snapshots enjoy themselves. If they fill up the datastore, they only kill all vms with snapshots, not the rest.

But how, you ask? You can edit the vmx files of you vms manually – which requires your vms to be powered down – and add the line: workingDir = “/vmfs/volumes//”

Or, you run my script and change the working location on the fly:

# Description:
# Set's the Working Location for a VM. This location will hold the vswap and snapshot delta files.
# Usage:
# First, connect to a virtual server server (Connect-VIServer)
# Set snapshot location for one vm (folder must already exist on datastore):
# Set-VMSnapshotLocation -vm VM001 -Location "[BigAssDatastore] Snapshots"
# For all vms at once (no folder specified will put all in the root of the datastore):
# Get-VM | ForEach-Object {Set-VMSnapshotLocation -vm $_ -Location "[BigAssDatastore]"}
# Reset the location to the original location (with the vmx file):
# Set-VMSnapshotLocation -vm VM001 -Reset
Function Set-VMSnapshotLocation
	param($vm, [string]$Location, [switch]$Reset=$False)
	#Region Input Validation
	# Check vm parameter
	If (!$vm)
		Throw "No VM specified."
	# Check Location parameter.
	# Can be empty when using Reset, can be "[datastore]" or can be "[datastore] folder" (folder must exist).
	If (!$Reset -and $Location -notmatch "\[\S+\](\s\w+)?")
		Throw "Invalid location specified. Syntax: [Datastore] Folder"
	# Specifying Reset will set Location to empty, which causes the original location to be used (same location as vmx file).
	If ($Reset)
		$Location = ""
	# Make sure to get a vm object to work with.
	# This allows both using a vm name when targeting one vm (Set-VMSnapshotLocation -vm VM001 -Reset);
	# AND piping a collection of vm's (Get-VM | ForEach (Set-VMSnapshotLocation -vm $_ -Location "[BigAssDatastore] Snapshots" ).
	If ($vm.GetType().Name -eq "String")
		$oVM = Get-VM $vm
	ElseIf ($vm.GetType().Name -eq "VirtualMachineImpl")
		$oVM = $vm
		Throw "Parameter vm is of an invalid type."
	#EndRegion InputValidation
	#Region Main
	# Get advanced properties of vm
	$vmView = $oVM | Get-View
	# Create object containing new properties
	$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
	$vmConfigSpec.Files = New-Object VMware.Vim.VirtualMachineFileInfo
	$vmConfigSpec.Files.SnapshotDirectory = $Location
	# Reconfigure VM using new properties
	#EndRegion Main

You can download it here: Set-VMSnapshotLocation (rename to .ps1)

I tried hard as I could, but I could not get my vm to die. Even running the script, creating a snapshot, running the script to move the working location again and deleting the snapshot did not prove a problem. However, I urge you to be careful with it. I’m not responsable for anything you do with it.

Tiny glitch: the VI Client shows the wrong datastore location when a vm has a snapshot in a modified workingdir.


Leave a Reply

Close Menu