Skip to content

Instantly share code, notes, and snippets.

@tjmichael81
Last active October 2, 2022 19:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjmichael81/32bdfb7fd3afd73a4d9502861fb94f0c to your computer and use it in GitHub Desktop.
Save tjmichael81/32bdfb7fd3afd73a4d9502861fb94f0c to your computer and use it in GitHub Desktop.
Use a date search to find and delete AWS AMI's and their corresponding disk snapshots
<#
### Resources: ###
# How-To Delete Unutilized EBS-Based AMIs And Corresponding Snapshots
# http://www.n2ws.com/how-to-guides/how-to-delete-unutilized-ebs-based-amis-and-corresponding-snapshots.html
# Deleting Snapshots by Using the AWS Tools for Windows PowerShell
# http://docs.aws.amazon.com/storagegateway/latest/userguide/DeletingSnapshotsUsingPowerShell.html
# Adding and Removing Items from a PowerShell Array
# http://www.jonathanmedd.net/2014/01/adding-and-removing-items-from-a-powershell-array.html
#>
# Script variables
$owner = "self"
$pauseTime = 60
# Date search criteria
$dateToday = [DateTime]::Now
$daysBack = 20
$searchDate = $dateToday.AddDays(-$daysBack)
# Create empty collections / arrays for storing AMI and snapshot ID's that meet the date search criteria
$instanceAMIs = @()
$amiCollection = {$instanceAMIs}.Invoke()
$volumeSnapshots = @()
$snapshotCollection = {$volumeSnapshots}.Invoke()
# Get all of the images owned by this user
$server_images = Get-EC2Image -Owner $owner
# Search for AMI's by date
# Add each of the AMI's that meet the search criteria to the AMI collection
foreach ($ami in $server_images) {
if ([DateTime]::Compare($searchDate, $ami.CreationDate) -gt 0) {
$amiCollection.Add($ami.ImageId)
}
}
# Search for snapshots based on the AMI's returned by the date search
# Add each snapshot ID to the snapshot collection
foreach ($amiID in $amiCollection) {
$instanceImage = Get-EC2Image $amiID
$snapshotCount = $instanceImage.BlockDeviceMapping.Count
for ($i=0; $i -lt $snapshotCount; $i++) {
$snapshotID = $instanceImage[0].BlockDeviceMapping[$i].Ebs | foreach {$_.SnapshotId}
$snapshotCollection += $snapshotID
}
}
# Informational message
$amiCount = $amiCollection.Count
"WARNING: THIS OPERATION WILL DEREGISTER THE FOLLOWING $amiCount AMI's:"
$amiCollection
"`n"
# Deregister each of the AMI's in the AMI collection
foreach ($amiID in $amiCollection) {
# Uncomment below to deregister AMI's
#Unregister-EC2Image $amiID
}
# Pause the script to allow for AMI unregisteration
Start-Sleep $pauseTime
# Informational message
$snapshotCount = $snapshotCollection.Count
"WARNING: THIS OPERATION WILL REMOVE THE FOLLOWING $snapshotCount SNAPSHOTS:"
$snapshotCollection
# Delete each snapshot in the snapshot collection
foreach ($snapshotID in $snapshotCollection) {
# Uncomment below to remove snapshots associated with AMI's
#Remove-EC2Snapshot $snapshotID -Force
}
@tjmichael81
Copy link
Author

Sample output if lines 62 and 76 are left commented:
ami deleter screenshot

@capn0jack
Copy link

capn0jack commented Apr 28, 2017

@tjmichael81, Thank you very much for this; it gave me a huge leg up! I did find one problem, though. I noticed right off the bat that sometimes the script would say that there was 1 more snapshot for a particular AMI than there really was. That's because this code returns the ephemeral block devices, as well as the EBS devices:

foreach ($amiID in $amiCollection) { $instanceImage = Get-EC2Image $amiID $snapshotCount = $instanceImage.BlockDeviceMapping.Count for ($i=0; $i -lt $snapshotCount; $i++) { $snapshotID = $instanceImage[0].BlockDeviceMapping[$i].Ebs | foreach {$_.SnapshotId} $snapshotCollection += $snapshotID } }

But the .ebs property is empty for ephemeral devices, leaving an empty entry at the end of the collection, which would generate an error during Remove-EC2Snapshot. So I borrowed the approach from https://www.yobyot.com/aws/deregister-an-aws-ami-and-remove-associated-s3-snapshots/2014/10/30/ and ended up with:

[EDIT] Oops, realized that that didn't properly account for multiple AMIs because I had boiled down my testing to doing one at a time. This is the right code:

foreach ($amiID in $amiCollection) { $instanceImage = Get-EC2Image $amiID $snapshotCollectionTemp = @($instanceImage.blockdevicemapping.ebs.snapshotid) $snapshotCollection = $snapshotCollection + $snapshotCollectionTemp } $snapshotCount = $snapshotCollection.count

Thanks,
Chaz

@tjmichael81
Copy link
Author

@capn0jack Thank you for the comments and update. From what I recall the AMI's that I was working with didn't have ephemeral storage attached, so I didn't account for them or encounter the error that you did. Thank you for posting a fix and link to the blog post!

--Tim

@mywayrk777
Copy link

Was very helpful. Thank you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment