July 30, 2008 - Johan

VMware Powershell script – Remove snapshots

On one of my previous articles Sven, who is actually a colleque of mine, asked if it would be possible to remove snapshots which were left unaccounted for. I reacted is a simple way: yeah, of course and as a matter of fact is is very easy. I really must say the guys from the VI Toolkit have done a great job on making a lot of complicated things very easy !! Hats off guys.

When I was doing a little background check for this I found another script made by Bas Vinken whichΒ can be found here, but what I like about Powershell scripting are what are known to be “Oneliners” all code on a single line. This is what shows the real power of powershell and that’s what I want to show everybody.

So when I created this script I had one thing in mind: “Keep it simple !”. Ok here the script:

$snap=get-snapshot -vm * ; remove-snapshot -snapshot $snap

What does it do ?

The Get-snapshot -vm * queries the connected VI server for all VM’s with associated snapshots, the $snap= statement puts these values in the variable $snap, the remove-snapshot commandlet uses this variable to …… commit the snapshot to the Virtual Disk. The “;” between the 2 commandlets is nothing else than a seperator instead of a hardreturn (otherwise it wouldn’t be a oneliner .. duh)

I cannot emphasize the importance of carefullness of using these types of scripts, whatif a snapshot has been made of a disk that has real userdata or an exchange database on it and you revert to a pre-snapshot state ? That’s why I really hope that everybody uses persistent disks for these kind of data containers. But fortunatly there is not an commandlet to revert to a previous snapshot.

Scripts Powershell / remove / snapshot /

Comments

  • Nice work Johan!

    Especially the fact that it’s a one-liner πŸ™‚

  • Rene says:

    Is there anyway to remove a VM completely via Powershell/Toolkit?

    • Sven Huisman says:

      This is from the help-file:
      C:\PS>Remove-VM ( Get-VM myVM ) -DeleteFromDisk

      Removes the MyVM virtual machine and deletes its files from the ESX server.

  • Mike says:

    How could you define a snapshot name? Say the _VCB-BACKUP_ snapshots. Would it be a bad idea to delete the VCB snapshots automagicly?

    • Hi Mike,
      You’ve got 2 questions, the answer to the first one:

      Actually that’s really easy to do; you have to make an selection with the where statement. I updated the powershell script I created previously:
      $snap= Get-Snapshot -vm *|where {$_.Name -match “VCB-Backup”} ; remove-snapshot -snapshot $snap

      You see it’s really easy..

      The answer to the second question: snapshots have an expiry date; let me explain: when you create a snapshot the domain password has a certain value, this value will change regularly so when you revert to a snapshot after the domain password has changed you need to remove the machine from the domain and add it again.

      That opens an discussion I will go into in a new article, the use and unuse of snapshots.

      I hope this answered your questions..

      grtx Johan

  • Mike says:

    Well the good news is I think the first part of the response was what I am looking for, need to test. The second part… Im not sure where you were going with that one. I must have been unclear but good info anyways πŸ™‚

    Thank you sir!

    • Hi Mike,

      You’re welcome πŸ™‚

      Let me put in other words: when you snapshot a machine and a user changes his data on a share, after some time you revert the snapshot, how do you think that user reacts when he finds out that his changed data has been reverted as well ?

      just my 2 cents

      grtx Johan

      • Johan,

        In the case of a file server, best practices indicate you would only snapshot the OS drive. You would then store files and home directories on a second hard drive and that drive would be marked independent so that its it not affected by snapshots. Of course you would still need to perform conventional backups of these files.

        • Hi Hal,

          Once again, you’re absolutely right, never snapshot user data. As a rule of thumb I only snapshot the systemdrive and make the data drives persistent ones.
          But what are the defaults and how many admins would or just stick to defaults ?

          My opinion on using snapshots keep them only as long as you need them to test the system (e.g. in case of servicepack or upgrade)

          grtx Johan

  • I’m sorry I missed your blog before now, you’ve got some good stuff here (and a nice theme). Some comments:

    1. The script can be made even shorter if that can be imagined, and this way feels a lot more logical to me. Once you use the pipeline, you will never go back…

    get-vm | get-snapshot | remove-snapshot

    And by the way–there is a cmdlet to revert to a previous snapshot. Check out Set-VM’s Snapshot parameter.

    -hal
    Co-Host, PowerScripting Podcast (powerscripting.net) and author of the upcoming Managing VI with PowerShell book.

    • Hi Hal,

      You’re absolutely right. I see what you mean: I rewrote the other oneliner:
      get-vm | get-snapshot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapshot

      Without the use of the variable it’s easier to read and the pipe handles it all..

      thanx we all learn from each other πŸ™‚

      grtx Johan

  • Mike says:

    Thanks all

  • Johen,

    You are right…the default setting is for a drive to be “dependent” I guess is the right way to say that.

    And yeah, I once had a problem back when I was new to VMware. I had about 20 VMs which I snapshot monthly as a part of a routine. After a few months I was experiencing some AWFUL perf issues. Turned out it was due to too many snapshots with too much churn. Snapshot removal took many, many hours. πŸ™‚

  • Mike says:

    Hello All,

    Thanks for your help in the past. After trying the script I have found that it runs and does what it should but I have a question.

    First, imagine an environment that had 50-100 ESX hosts with hundreds of VMs. One might find several to a dozen VM’s daily with snapshots left out there.

    How could I run the script; get-vm | get-snapshot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapshot where confirmation wasn’t needed for each? I have added the -confirm$false but it resulted in timeout errors and looked like it might have overburdened a ESX host. The host appeared offline until I killed the script.

    The following is the error that resulted.

    PS C:\Program Files\VMware\Infrastructure\VIToolkitForWindows> get-vm | get-snap
    shot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapshot -confirm:$false
    Remove-Snapshot : 10/8/2008 5:13:06 PM Remove-Snapshot D4B5D67A-77FD-4EE0
    -A842-2A4E3021802D The operation for the entity vm-13948 failed with the fol
    lowing message: “Operation timed out.”
    At line:1 char:76
    + get-vm | get-snapshot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapshot
    <<<< -confirm:$false
    Remove-Snapshot : 10/8/2008 5:25:13 PM Remove-Snapshot D4B5D67A-77FD-4EE0
    -A842-2A4E3021802D The request refers to an object that no longer exists or
    has never existed.
    At line:1 char:76
    + get-vm | get-snapshot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapshot
    <<<< -confirm:$false
    Remove-Snapshot : 10/8/2008 5:25:13 PM Remove-Snapshot D4B5D67A-77FD-4EE0
    -A842-2A4E3021802D The request refers to an object that no longer exists or
    has never existed.
    At line:1 char:76
    + get-vm | get-snapshot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapshot
    <<<< -confirm:$false
    Remove-Snapshot : 10/8/2008 5:25:13 PM Remove-Snapshot D4B5D67A-77FD-4EE0
    -A842-2A4E3021802D The request refers to an object that no longer exists or
    has never existed.
    At line:1 char:76
    + get-vm | get-snapshot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapshot
    <<<< -confirm:$false
    Remove-Snapshot : 10/8/2008 5:25:14 PM Remove-Snapshot D4B5D67A-77FD-4EE0
    -A842-2A4E3021802D The request refers to an object that no longer exists or
    has never existed.
    At line:1 char:76
    + get-vm | get-snapshot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapshot
    <<<

    I would like to automate this clean up. As long as that _VCB-Backup_ is the qualifier I am ok with it running automaticly.

    Thanks again,

    Mike

  • Mike says:

    The snapshots did appear to clean themselves up but the effects are definately unacceptable.

  • Tim says:

    Mike- I guess nobody has an answer for you!

  • Hi Mike,

    Sorry that I haven’t seen your comment sooner, you could have mailed me for speeding up things. One thing I noticed with the commandline is that you have a : between -confirm and $false that should not be the case ..

    grtx Johan

    • Mike says:

      Hi Johan,

      Here is the result of what I interpreted from your comments.

      PS C:\Program Files\VMware\Infrastructure\VIToolkitForWindows> get-vm | get-snapshot|Where {$_.Name -match “_VCB-Backup_”}|remove-snapsh
      ot -confirm $false
      Remove-Snapshot : A parameter cannot be found that matches parameter name ‘False’.
      At line:1 char:100
      + get-vm | get-snapshot|Where {$_.Name -match “_VCB-Bac
      kup_”}|remove-snapshot <<<< -confirm $false

  • Mike says:

    Get-VC virtualcenter-server.name

    get-vm | get-snapshot|Where {$_.Name -match β€œ_VCB-Backup_”}|remove-snapshot -RunAsync -confirm:$false

    Seems to be working in two lines…

    From what I can tell the -RunAsync resolved the timeout/runaway behavior. The colon was needed in this case.

  • Mike says:

    Ok well the new version of the VItoolkit has changed the syntax so here is my copy of the newest

    connect-viserver virtualcenter-server.name
    get-vm | get-snapshot -Name β€œ_VCB-Backup_”|remove-snapshot -RunAsync -confirm:$false

  • […] all snapshots for the VMs in vCenter using perl, so I spent a few minutes on this script. There are a lot of scripts for creating and deleting snapshots (and a couple to show them) using powershell, but […]

  • Hussain says:

    How to run this script?

    Thanks,

  • mr says:

    get-snapshot * | removesnapshot

  • somasundar says:

    can you please tell me the script to start a vm using a particular snapshot. My intention is to revert the vm using script.

  • chrisqc says:

    Hi Mike

    Your script works well.
    But if there is no _VCB-BACKUP_ snapshot, an error message is returned telling you that no snapshot were found.
    How can you write your script to test if there is no snapshot do nothing, else delete the _VCB-BACKUP_ snapshot.

    Thanks

    Chris

  • Daniel says:

    How can you schedule this script to run automatically from vsphere powercli? Not sure how to add this to the script to open Vsphere power cli and execute the command.

    Script:
    connect-viserver virtualcenter-server.name
    get-vm | get-snapshot -Name β€œ_VCB-Backup_”|remove-snapshot -RunAsync -confirm:$false

  • Stefan says:

    Hi Guys

    I was looking for a way to automatically delete snapshots, that are older than one week (or another time, depends on the company policy). Is there some variable that specifys the time of the snapshot? I’d like to recommit all snapshots older than a week to prevent problems with full VMFS and timeout while recommitting big snapshots.

    The script we use here could be useful in that case. Does anyone see a way here?

    Thanks,
    Stefan

  • william says:

    hi there,

    i want to delete snapshot left by Vranger on my vmware enviroment, what type of wild card can i use to do this,
    vranger names the snap shot “Created by vRanger …..”
    and is there a way i can say not to delete snap shots older than a day?

  • Thom says:

    Can this be ran on a cascaded basis? For example:

    Once more than “x” snapshots are being removed wait until the process is completed before continuing.

  • Thom says:

    I am VERY new to PS and VB scripting.

    My goal is to write a script that will:

    1) shut all guests down.
    2) Take a snapshot of all guests in a cascaded fashion
    3) Power the guests back on
    4) Call (what you use to patch your servers)
    5) Reboot all guests

    I know that is a tall order (especially for a rookie like me) but I am positive it can be done.

    Advice?