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/<insanely long guid you need to somehow find>/”

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
		}
	Else
		{
		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
	$vmView.ReconfigVM($vmConfigSpec)
	#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.

Enjoy.

Tagged with:
 

14 Responses to Set VMware Snapshot Location with Powershell

  1. dboftlp v12n says:

    Fiyah Powah!
    Look at the guns on that bad boy!
    Nice!

  2. Wolfi says:

    Hi,

    great Script. I search for an script about snapshot. With Defines who has created, deleted an the timestamp about this.

    Can you help me about this???

    thanks

    • admin says:

      Hi Wolfi,
      Tanks.
      I don’t have the time to write a script for you right away. But search for PowerCLI Snapshots Get-VIEvent and you might find something.
      I know the info you need is not included in the properties of a snapshot, so you have to retrieve it from the event generated when a snapshot is created.
      Hugo

      »crosslinked«

  3. Changing snapshot location without VM downtime « a CraZy PeNguIn says:

    […] Get the script and more info here […]

  4. Craig says:

    Does this script work with vCenter 4.1? When I run it, nothing happens.

  5. Marty says:

    where did you get the Set-VMSnapshotLocation cmdlet?

  6. Eddie B says:

    Love the script – thanks.

    Your script sets the workingdir which affects both swap and snapshots, but I’d like to keep my swap files with the vm. Do you know how to set sched.swap.dir on-the-fly? I can only find references to editing the vmx file.

  7. Todd Rorie says:

    Running the command on one VM comes back with Set-VMSnapshotLocation is not recognized as the name of a cmdlet. We are running 4.1 U1. Cannot find any mention of this cmdlet anywhere except your site. Something I need to add to PowerCLI to get this to work? Thanks.

  8. Carl Knox says:

    I struggled a bit with getting this to work. Here’s how I got it to work.

    PS>> .”C:\Scripts\Set-VMSnapshotLocation.ps1″
    PS>> Set-VMSnapshotLocation -vm vm01 -location “datastore”
    PS>> Set-VMSnapshotLocation -vm vm01 -location “datastore”

    The first line adds the function(s) within the .ps1 file to your PS session, which can then be called directly with parameters. I’ll probably rename the .sp1 file to something shorter, in my environment.

  9. Carl Knox says:

    The key to adding the function was the fully qualified path. Using .\Set-VMSnapshotLocation.ps1 from my scripts folder did not add the function to my session.

    You should verify the function was added before executing…

    PS>> get-childitem function:set*

  10. Carl Knox says:

    My previous email might be misleading. You should be at a PowerCLI prompt, not a PowerShell prompt.

    PowerCLI>> .”C:\Scripts\Set-VMSnapshotLocation.ps1″
    PowerCLI>> Set-VMSnapshotLocation -vm vm01 -location “[datastore]”
    PowerCLI>> Set-VMSnapshotLocation -vm vm02 -reset

  11. Robert Roose says:

    Can anyone confirm that this script functions on vmware 5.1??

  12. shailendra kumar says:

    This script is running but without any success…..any clue????

Leave a Reply