Skip to content

Instantly share code, notes, and snippets.

@breiter
Last active December 30, 2015 21:29
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 breiter/7887782 to your computer and use it in GitHub Desktop.
Save breiter/7887782 to your computer and use it in GitHub Desktop.
Script to back up a Windows EBS volume on EC2 to S3 by snapshot.
#backup a disk by snapshot to S3.
param
(
[string] $path, #directry to clean of old files
[int] $diskNumber,
[string] $ec2VolumeId, #volumn arn in ec2
[string] $description,
[int] $days = 2
);
function aws { & 'C:\Program Files\Amazon\AWSCLI\aws.exe' $args; }
function Snapshot-Disk([int] $diskNumber, [string] $ec2VolumeId, [string] $description)
{
#un-mount drive before snapshot
UnMount-Disk $diskNumber;
Write-Host "aws ec2 create-snapshot --volume-id $ec2VolumeId --description $description"
$result = (aws ec2 create-snapshot --volume-id $ec2VolumeId --description $description) -join "`n" | ConvertFrom-Json;
#poll until job is compmleted
while((Get-SnapshotProgress $result.snapshotId) -lt 100)
{
Write-Host "Sleep 60 seconds.";
Start-Sleep 60; #wait 1 minute
}
#mount drive again
Mount-Disk $diskNumber;
}
function Get-SnapshotProgress([string] $snapshotId)
{
Write-Host "Get-SnapshotProgress $snapshotId."
#result is in JSON format. It gets automatically split into a string[] by powerhsell on newlines
#when it retrieves the return value from the aws cli process.
#convert array back to string in order to pass to ConvertFrom-Json
$result = (aws ec2 describe-snapshots --snapshot-ids $snapshotId) -join "`n" | ConvertFrom-Json;
$progress = 0;
if($result.Snapshots.Progress) {
$progress = [int]$result.Snapshots.Progress.TrimEnd('%');
}
Write-Host "Progress: $progress%.";
return $progress;
}
function UnMount-Disk([int] $diskNumber)
{
Write-Host "Unmount disk $diskNumber.";
Get-Disk -Number $diskNumber | Set-Disk -IsOffline:$true;
}
function Mount-Disk([int] $diskNumber)
{
Write-Host "Mount disk $diskNumber.";
Get-Disk -Number $diskNumber | Set-Disk -IsOffline:$false;
Get-Disk -Number $diskNumber | Set-Disk -IsReadONly:$false;
}
function Remove-OldFiles(
[string] $Path = ".", # directory to clean
[int] $Days = 2, #days of grace. files older than $Days will be deleted
[Switch] $Whatif
)
{
Write-Host "Clean files from $Path over $Days days old."
$now = [DateTime]::Now;
Get-ChildItem $Path -Recurse | Foreach-Object {
if( !$_.PsIsContainer -and ($now-$_.LastWriteTime).Days -ge $Days ){
if( $Whatif ) {
Write-Output "Remove-Item $($_.FullName)";
} else {
Remove-Item $_.FullName;
}
}
}
}
& {
Import-Module Microsoft.PowerShell.Utility
Write-Host "Begin: $(Get-Date)";
Snapshot-Disk $diskNumber $ec2VolumeId $description;
Remove-OldFiles $path $days;
Write-Host "End: $(Get-Date)";
}
@breiter
Copy link
Author

breiter commented Dec 10, 2013

How to Use

  • Step 1: write data to volume -- such as SQL Server backup.
  • Step 2: Invoke this script

Script Execution

  • Dismount EBS volume from Windows
  • Create snapshot of volume to S3 - Poll until snapshot is complete
  • Mount EBS volume in Windows again
  • Clean old files from volume Disk Number comes from Get-Disk cmdlet.

Run as a scheduled job like this (where -path is the Windows filesystem path, -diskNubmer is the mount number in Windows and -ec2VolumneId is the EBS volume in EC2):

powershell.exe -file "C:\Program Files\Utility\Invoke-BackupJob.ps1" -path D:\ -diskNumber 2 -ec2VolumeId vol-XXXXXXXX -description "Important Server Backup" > "C:\Program Files\Utility\log.txt"

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