Remove EC2 instance snapshots older than X days

Guess who was lazy and didn’t post anything for months? 🙂

Let’s fix that!

Newest challenge: “I’m spamming New-EC2Snapshot every minute because I need my instance to be super protected against hacker ninjas! (Or was it pirates?) But now I have 6.022×1023 snapshots I have no idea what to do with!”

How to get rid of all snapshots older than 3, 7, 30 days?

First, we’ll need to get all snapshots. All your snapshots!

If you try something like Get-EC2Snapshot you’ll be unpleasantly surprised. Aside from getting a bunch of useless information about public snapshots (~10.000), command will take ~10 seconds to execute. Still, around 3x faster than running Get-EC2Image

We need to specify -Owner parameter. And it’s your AWS account ID.

Nice. Now we know there are only 200 snapshots we don’t need, as opposed to earlier 10k.

Let’s run through each snapshot ( foreach ($Snapshot in $AllSnapshots) { ... } ) in our new, beautiful, collection and check which ones are way too old and make our collection less beautiful.

To do so, we’ll compare StartTime snapshot property against today’s date minus number of days we want to keep snapshots.

If we’re interested in keeping them for only a week, the check would look like this:

Now that we identified which ones need to go, we should put them in an ugly bucket to be taken away. We will create a nice new object containing relevant information like start times, snapshot and volume IDs and pack them in an array.

Make sure to make $AllSnapshotsForRemoval an array first:

We have all old snapshots identified and bunched up together in $AllSnapshotsForRemoval array.

Let’s do another run through all the elements ( foreach ($SnapshotToRemove in $AllSnapshotsForRemoval) { ... } ) and call Remove-EC2Snapshot.

We’ll quickly see how many snapshot removals fail as they are currently in use by our AMI images. Therefore, a basic try/catch block is in order.

But what if we don’t want to remove snapshots blindly? There should be a way for us to check if the output is indeed what we want and then proceed with removal.

We will include a -Force parameter which will tell us when to Use the Force and remove snapshots. Otherwise, the script is going to run in a summary mode.

To quickly check for user input (this is not a function, so no Param available) we can parse input arguments from the user, if any, and check if user is a Jedi and wants to use the Force:

Or, a bit compressed:

If user used -Force in any capitalization, we have our trigger to kick the ugly $AllSnapshotsForRemoval bucket.

And that is all.

We need the user to provide us with an AWS account ID and a number of days to keep the snapshots alive. These can also be taken as input parameters, like -Force switch, but a proper way to do this is with a function and I didn’t really feel like making one.

Perhaps in another version of the script. Also, it can be a good homework for you. Make sure to send it to me if you do change it 🙂

Hopefully, you found this short training interesting.

But if the script is all you came here for, here it is:

Have fun!


  1. Chris Reply

    This was a lifesaver. Thanks

  2. Kathleen Shea Reply

    Thank you!

  3. Six Reply

    I was a bad webmaster and have left the site without a care for over a year. Still, it makes me happy that my scribblings were able to help someone in the meantime 🙂

Leave a Comment