Automate Removal of VM Snapshots

Automate Removal of VM Snapshots

When I come up with an idea for a blog post, normally I don’t review what ideas I have already wrote about.  I should because I would have noticed another post about snapshots I wrote earlier this year.  This post is different as it has more cowbell, err automation.  Everybody loves automation right?  I normally write about what is happening in real life at the time.  So more snapshot fun time.  🙂

Snapshots, while they’re great for the time you performed an upgrade that didn’t go as planned, or you removed the certificate for ADFS  without installing the new one, but a form of long term backup they are not.  I have found many issues having snapshots longer than needed.  Try expanding the virtual disk of the production server that is about out of space that has a 1 TB snapshot for example, better grab some popcorn you be there for a while.  Having old snapshots lead to performance issues due to the way that they work.  All of this said, I have a few customers that still think that snapshots can and should be used as a long term backup solution.

Seriously didn't you know this about snapshots?
Even Yoda knows about snapshots

In my work environment was have a policy that we will leave snapshots for 14 days before deleting them, no exceptions.  While this might not seem like a long time they were getting to a point that it got overlooked many times and not getting cleaned up as they should.  There were several times that we had snapshots over a month old and in the the terabytes in size.  So to combat this issue, PowerCLI and Task Scheduler to the rescue.

PowerCLI to Rid the World of Snapshots

So as I stated earlier, 14 days is the maximum age for any VM snapshot in my environment.  So to gather said snapshots of deletion age, run the following:

$SnapshotAge = (Get-date).AddDays(-14)
$VMs = Get-VM | Get-Snapshot | Where Created -lt $SnapshotAge

Once we have gathered the snapshots that are ready for deletion, I select the first 10 and delete them by running the following:

$Snapshots = $VMs | Select -First 10 | Remove-Snapshot -RunAsync -Confirm:$false
$Tasks = Get-task -id $snapshots.id | Where PercentComplete -ne "100"

I monitored the deletion tasks and once the 10 were completed, it would start more if applicable by using this loop:

Do {
            $VMs = Get-vm | Get-Snapshot | Where Created -lt $SnapshotAge
            sleep -Seconds 5
            $Tasks = Get-task -id $Snapshots.id | Where PercentComplete -ne "100"
            If($($Tasks.count) -eq 0){
                $VMs = Get-VM | Get-Snapshot | Where Created -lt $SnapshotAge
                Sleep -Seconds 5
                $Snapshots = $VMs | Select -First 10 | Remove-Snapshot -RunAsync -Confirm:$false
            }
            else{
                #"There are still $($tasks.count) task(s) running"
            }
        }
        While ($($VMS.count) -gt '0')

Normally we don’t have more than 10 snapshots, but when we do I don’t want more than 10 deletions rolling at a time.

-Stuart

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.