Snapshots for Maintenance or Maintenance for Snapshots…
During our last maintenance window for our VMware environment, my team updated VMware Tools, hardware and aligned vNUMA. So before we started this work we took snapshots of all of the VMs there were getting the updates. Fast forward a few days, and now we have 600+ snapshots that need to be deleted.
Automating Snapshots Removal with PowerCLI
With having 600+ snapshots I didn’t just want to delete them all at once. So since these were generated with a script they all have the same name, so I can use that to target them.
$AllNamedSnapshots = Get-cluster NonProductionCluster | Get-vm | Get-Snapshot | Where Name -eq "PreToolsandHardware20180310"
This will return all of the snapshots that were generated on this cluster with the give name in to an array.
$RemoveSnapshotTasks = $AllNamedSnapshots | Select -First 15
This will select the first 15 snapshots so it can be feed into the next line of code shown below.
foreach($SnapShottobeRemoved in $RemoveSnapshotTasks){ $Tasks[(Remove-Snapshot $SnapShottobeRemoved -RunAsync -Confirm:$false).id] = $SnapShottobeRemoved }
This is the line that makes the magic happen. It will start the snapshot removal and add the task ids to a hash table. The reason for a hash table here is that it is easier to manipulate the data later on in the script.
Zip the Snaps
Now to put these lines together and delete the snapshots, I give you the completed script.
$AllNamedSnapshots = Get-cluster NonProductionCluster | Get-Snapshot | Where Name -eq "PreToolsandHardware20180310" $SnapshotRemaining = $AllNamedSnapshots.count $Tasks = @{} While ($SnapshotRemaining -gt 0){ $RemoveSnapshotTasks = $AllNamedSnapshots | Select -First 15 foreach($SnapShottobeRemoved in $RemoveSnapshotTasks){ $Tasks[(Remove-Snapshot $SnapShottobeRemoved -RunAsync -Confirm:$false).id] = $SnapShottobeRemoved } $RunningTasks = $Tasks.count While ($RunningTasks -gt 0){ Get-Task | % { If($tasks.containskey($_.id) -and $_.state -eq "Success"){ $tasks.Remove($_.Id) $RunningTasks-- $SnapshotRemaining-- } } Start-Sleep -Seconds 10 Write-host "There are still $RunningTasks task(s) running" -BackgroundColor Black -ForegroundColor Yellow } $AllNamedSnapshots = Get-cluster NonProductionCluster | Get-Snapshot | Where Name -eq "PreToolsandHardware20180310" }
The below is what the output of the script looks like when it is running correctly.
This is a handle little script that we are going to use for many purposes. I can easily modify the line that gathers the snapshots to instead of looking for name snapshots, but look for snapshots older the 14 days to automatically remove them and run it via a schedule tasks or setup it in vRealize Orchestrator.
The one caveat with this script is that if one of the 15 snapshots takes a long time to remove the script has to wait. There is a way to check for these conditions and skip them, but that’s another post.
-Stuart