Finding Old Snapshots with PowerShell

Finding Old Snapshots with PowerShell

Do you need to find Old Snapshots on a hyper-v server? It’s super easy. So, today we will go through how to get some basic information that allows us to make judgment calls.

The Script – Find Old Snapshots

$Date = (Get-Date).AddDays(-7)
$Vms = Get-VM | where-object { $_.state -like "Running" } 
$Return = foreach ($VM in $Vms) {
    $SnapShots = $VM | Get-VMSnapshot
    foreach ($SnapShot in $SnapShots) {
        if ($snapshot.creationTime -lt $date) {
            [pscustomobject]@{
                SnapShotName         = $SnapShot.name
                SnapShotCreationDate = $SnapShot.CreationTime
                VituralMachine       = $SnapShot.VmName
                Host                 = $SnapShot.ComputerName
            }
        }
    }
}
$Return

The Breakdown

The first part of the script is getting the age requirements. In this case, we want to know anything older than 7 days. So we use the Get-Date command. We add -7 days and this will give us the date to compare by.

$Date = (Get-Date).AddDays(-7)

In this case, we only want the running machines. The reason I want running machines is that the powered-off machines might be in a decommissioning process or for other reasons. So we look at the state of each VM to see if it’s “Running”. We do this with a where-object.

$Vms = Get-VM | where-object { $_.state -like "Running" } 

Now we have the running VMs to work with, we want to get each one’s snapshot. We want to compare each snapshot to see if it’s older than the date. The information we want is the name of the snapshot, the snapshots creation date, the vm, and the hostname. So we start for each loop. Inside the look, we ask with an if statement the creation time is less than the date we created earlier. Then from there we create a PS custom object and pull out the information we want.

$Return = foreach ($VM in $Vms) {
    $SnapShots = $VM | Get-VMSnapshot
    foreach ($SnapShot in $SnapShots) {
        if ($snapshot.creationTime -lt $date) {
            [pscustomobject]@{
                SnapShotName         = $SnapShot.name
                SnapShotCreationDate = $SnapShot.CreationTime
                VituralMachine       = $SnapShot.VmName
                Host                 = $SnapShot.ComputerName
            }
        }
    }
}

Then finally we output the $return value. We can export this to a CSV and drop it into a file share. I personally do this with a nextcloud instance. You can read more about that here. Another option is to email the report using a Microsoft Graph API or an SMTP email system. Finally, if you have confidence in your choice, you can delete the VMs.

Conclusion

Running this script and combining it with the file drop and a few other pieces of automation changed how I worked with multiple clients. This was a good cleanup process and saved many of my clients’ much-needed storage space. Let me know how you use this code for your systems.