While AWS provides excellent infrastructure for running Windows Server instances, many administrators are surprised to find no built-in solution for automated EBS snapshot scheduling. Unlike Linux systems where cron jobs and bash scripts are common, Windows environments require a different approach.
For Windows Server 2003/2008 instances, PowerShell offers the most robust automation capabilities. Here's a complete script that handles:
- Instance identification
- Volume enumeration
- Snapshot creation
- Tagging for organization
# AWS EC2 Daily Snapshot Script for Windows
# Requires AWS Tools for Windows PowerShell
# Configuration
$awsAccessKey = "YOUR_ACCESS_KEY"
$awsSecretKey = "YOUR_SECRET_KEY"
$region = "us-east-1"
$retentionDays = 7
# Initialize AWS connection
Set-AWSCredentials -AccessKey $awsAccessKey -SecretKey $awsSecretKey
Set-DefaultAWSRegion -Region $region
# Get current instance ID
$instanceId = (Invoke-RestMethod -Uri "http://169.254.169.254/latest/meta-data/instance-id").Content
# Get all attached volumes
$volumes = (Get-EC2Instance -InstanceId $instanceId).Instances.BlockDeviceMappings.Ebs.VolumeId
# Create snapshots with descriptive tags
foreach ($volume in $volumes) {
$snapshotTag = @{
Key = "Name"
Value = "DailyBackup-$(Get-Date -Format 'yyyyMMdd')"
}
$snapshot = New-EC2Snapshot -VolumeId $volume -Description "Daily backup of $volume"
New-EC2Tag -Resource $snapshot.SnapshotId -Tag $snapshotTag
Write-Output "Created snapshot $($snapshot.SnapshotId) for volume $volume"
}
# Cleanup old snapshots
$oldDate = (Get-Date).AddDays(-$retentionDays)
$oldSnapshots = Get-EC2Snapshot | Where-Object {
$_.Tags.Key -eq "Name" -and $_.Tags.Value -like "DailyBackup*" -and $_.StartTime -lt $oldDate
}
foreach ($snap in $oldSnapshots) {
Remove-EC2Snapshot -SnapshotId $snap.SnapshotId -Force
Write-Output "Deleted old snapshot $($snap.SnapshotId)"
}
To run this daily at 2 AM:
- Save the script as
C:\Scripts\EC2DailySnapshot.ps1
- Open Task Scheduler
- Create Basic Task
- Set trigger to "Daily" at 2:00 AM
- Action: "Start a program"
- Program:
powershell.exe
- Arguments:
-ExecutionPolicy Bypass -File "C:\Scripts\EC2DailySnapshot.ps1"
For those preferring not to manage scripts:
- AWS Systems Manager Automation: Create maintenance windows to run snapshot commands
- AWS Lambda with CloudWatch Events: Serverless solution using Python/Node.js
- Third-party tools: Skeddly or CloudRanger for GUI-based management
When implementing this solution:
- Store AWS credentials securely using IAM roles or AWS Systems Manager Parameter Store
- Monitor snapshot storage costs
- Test restoration process regularly
- Consider multi-region replication for critical data
When managing EBS-backed Windows instances (including legacy systems like Server 2003/2008), creating automated daily snapshots presents unique challenges compared to Linux environments. The AWS Management Console doesn't provide native scheduling for this operation, requiring custom solutions.
Before implementing any solution, we need to account for:
- Instance consistency (VSS-aware snapshots for Windows)
- Multiple attached EBS volumes
- AWS API rate limits
- Snapshot cleanup policies
- Permission management (IAM roles)
Here's a production-tested PowerShell script that handles both root volumes and additional EBS attachments:
# Requires AWS Tools for PowerShell
Import-Module AWSPowerShell
# Configuration
$retentionDays = 7
$region = "us-west-2"
$descriptionPrefix = "DailyAutoSnapshot-"
# Get current date for snapshot naming
$currentDate = Get-Date -Format "yyyyMMdd"
# Get instance metadata
$instanceId = (Invoke-WebRequest -Uri "http://169.254.169.254/latest/meta-data/instance-id").Content
$allVolumes = (Get-EC2Instance -Region $region -InstanceId $instanceId).Instances.BlockDeviceMappings
foreach ($volume in $allVolumes) {
$volumeId = $volume.Ebs.VolumeId
# Create snapshot
$snap = New-EC2Snapshot -Region $region -VolumeId $volumeId -Description "$descriptionPrefix$currentDate"
# Tag the snapshot
$tag = New-Object Amazon.EC2.Model.Tag
$tag.Key = "BackupType"
$tag.Value = "DailyAuto"
New-EC2Tag -Region $region -Resource $snap.SnapshotId -Tag $tag
# Cleanup old snapshots
$oldSnaps = Get-EC2Snapshot -Region $region -Filter @{Name="description";Values="$descriptionPrefix*"} |
Where-Object { $_.StartTime -lt (Get-Date).AddDays(-$retentionDays) }
foreach ($old in $oldSnaps) {
Remove-EC2Snapshot -Region $region -SnapshotId $old.SnapshotId -Force
}
}
To run this daily, create a scheduled task on your Windows instance:
$trigger = New-ScheduledTaskTrigger -Daily -At 2am
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\EBSSnapshots.ps1"
Register-ScheduledTask -TaskName "AWS Daily Snapshots" -Trigger $trigger -Action $action -RunLevel Highest
For those preferring not to handle scripting:
- AWS Systems Manager Automation: Create maintenance windows with SSM documents
- Lambda + CloudWatch Events: Serverless approach using instance tags
- Third-party tools: Skeddly or CloudRanger (now part of Dell)
For enterprise environments, consider adding:
- Error handling and logging
- SNS notifications for failures
- Cross-region replication
- Encryption management
- Cost allocation tags