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.
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 $SnapshotAgeOnce 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