Created
April 19, 2015 11:33
-
-
Save Sam-Martin/5e1f9bf73643662c0bf5 to your computer and use it in GitHub Desktop.
Snapshot EBS Volume and copy snapshot to another region
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.Synopsis | |
Creates a snapshot of an EBS volume, copies it to the destination region, then deletes the snapshot (not the volume) in the source region | |
.DESCRIPTION | |
You will need to run either Set-AWSCredentials or Initialize-AWSDefaults passing your accesskey and privatekey prior to execution of this cmdlet in order to establish connectivity to AWS. | |
.NOTES | |
To set the default AWS credentials for your current Windows user, use: | |
Initialize-AWSDefaults -AccessKey ***** -SecretKey ***** -Region us-west-2 | |
Naturally you will need to replace the asterisks and region with the values appropriate to your configuration | |
.EXAMPLE | |
New-EC2VolumeSnapshotOffsite -volumeName "TKYMGMT01 Full Backup Z:" -sourceRegion ap-northeast-1 -destinationRegion ap-southeast-2 -Confirm:$false -verbose | |
.EXAMPLE | |
New-EC2VolumeSnapshotOffsite -volumeName "TKYSQL01 Z: Backup" -sourceRegion "ap-northeast-1" -destinationRegion "ap-southeast-2" -Description "Backup and offsite of TKYSQL01 Z: Backup on $((get-date).ToString('yyyy-MM-dd HH:mm:ss'))" -snapshotName "Automatic Offsiting" -Verbose -confirm:$false | |
.OUTPUTS | |
Amazon.EC2.Model.Snapshot (destination) | |
#> | |
function New-EC2VolumeSnapshotOffsite | |
{ | |
[CmdletBinding( | |
SupportsShouldProcess=$true, | |
PositionalBinding=$false, | |
ConfirmImpact='High')] | |
#[OutputType([Amazon.EC2.Model.Snapshot])] | |
Param | |
( | |
# Volume Name | |
[Parameter(Mandatory=$true, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=0, | |
ParameterSetName='Volume by name')] | |
[ValidateNotNullOrEmpty()] | |
[string]$volumeName, | |
# Source Region | |
[Parameter(Mandatory=$true, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=1)] | |
[ValidateNotNullOrEmpty()] | |
[string]$sourceRegion, | |
# Destination Region | |
[Parameter(Mandatory=$true, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=2)] | |
[ValidateNotNullOrEmpty()] | |
[string]$destinationRegion, | |
# Snapshot Description | |
[Parameter(Mandatory=$false, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=3)] | |
[string]$description= "Backup and offsite of $volumeName on $((get-date).ToString('yyyy-MM-dd HH:mm:ss'))", | |
# Snapshot Name | |
[Parameter(Mandatory=$false, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=4)] | |
[string]$snapshotName | |
) | |
Begin | |
{ | |
# Check the AWS module is loaded | |
if(!(Get-Module | ?{$_.Name -eq "AWSPowerShell"})){ | |
# Check the AWS module is installed | |
if(Get-Module -ListAvailable | ?{$_.name -eq "AWSPowerShell"}){ | |
# Import AWS module | |
Import-Module AWSPowerShell | |
}else{ | |
Throw "Please install the AWS module."; | |
} | |
} | |
# Check we've got AWS creds loaded | |
if(!(Get-AWSCredentials -ListStoredCredentials)){ | |
Throw "No AWS credentials loaded. Use Set-AWSCredentials or Initialize-AWSDefaults to set credentials."; | |
} | |
} | |
Process | |
{ | |
if ($pscmdlet.ShouldProcess("$volumeName", "Taking snapshot")) | |
{ | |
# Take Snapshot | |
Write-Verbose "Taking snapshot of $volumeName"; | |
try{ | |
$snapshot = New-EC2Snapshot -Description $description -VolumeId $(Get-EC2Volume -Region $sourceRegion | ?{$_.tag | %{$_.value -eq $volumeName }} ).VolumeId -ErrorAction Stop | |
}catch{ | |
Throw $_.exception.message; | |
} | |
# Wait for the snapshot to finish being created | |
while(($snapshotStatus = (Get-EC2Snapshot -SnapshotId $snapshot.SnapshotId -Region $sourceRegion)).Status -eq "pending"){ | |
Write-Verbose "Sleeping for 20 seconds as snapshot still pending $($snapshotStatus.progress)"; | |
sleep -s 20 | |
} | |
# Check the snapshot was created successfully | |
if($snapshotStatus.Status -eq "completed"){ | |
Write-Verbose "Snapshot complete"; | |
}else{ | |
Throw $snapshotStatus | |
} | |
} | |
if ($pscmdlet.ShouldProcess("$destinationRegion", "Copying snapshot")) | |
{ | |
# Copy snapshot to destination region | |
Write-Verbose "Copying snapshot from $sourceRegion to $destinationRegion"; | |
try{ | |
$snapshotCopy = Copy-EC2Snapshot -Description $description -SourceRegion $sourceRegion -Region $destinationRegion -SourceSnapshotId $snapshot.SnapshotId -ErrorAction stop | |
}catch{ | |
Throw $_.exception.message; | |
} | |
# Wait for the snapshot to copy | |
while(($snapshotCopyStatus = Get-EC2Snapshot -SnapshotId $snapshotCopy -region $destinationRegion).status -eq "pending"){ | |
Write-Verbose "Sleeping for 20 seconds as snapshot still copying $($snapshotCopyStatus.progress)"; | |
sleep -s 20 | |
} | |
# Check the snapshot copied successfully | |
if($snapshotCopyStatus.Status -eq "completed"){ | |
Write-Verbose "Snapshot complete"; | |
}else{ | |
Throw $snapshotCopyStatus | |
} | |
# Set the name of the snapshot | |
$tag = New-Object Amazon.EC2.Model.Tag | |
$tag.Key = "Name" | |
$tag.Value = $snapshotName | |
New-EC2Tag -ResourceId $snapshotCopy -Tag $tag -Region $destinationRegion | |
} | |
if ($pscmdlet.ShouldProcess("$volumeName", "Deleting original snapshot")) | |
{ | |
# Delete original snapshot | |
Write-Verbose "Deleting original snapshot of $volumeName in $sourceRegion"; | |
try{ | |
$snapshotDelete = Remove-EC2Snapshot -SnapshotId $snapshot.SnapshotId -Region $sourceRegion -Force -ErrorAction stop | |
}catch{ | |
Write-Error $_.exception.message; | |
} | |
# Wait for deletion to complete | |
while(($snapshotDeleteStatus = Get-EC2Snapshot -SnapshotId $snapshotDelete -region ap-southeast-2).status -eq "pending"){ | |
Write-Verbose "Sleeping for 20 seconds as snapshot still deleting $($snapshotDeleteStatus.progress)"; | |
sleep -s 20 | |
} | |
# Check deletion was successful | |
if($snapshotDeleteStatus.Status -eq "completed"){ | |
Write-Verbose "Snapshot deletion complete"; | |
}else{ | |
Throw $snapshotDeleteStatus | |
} | |
} | |
if ($pscmdlet.ShouldProcess("$destinationRegion", "Returning snapshot in destination") -and $snapshotCopy) | |
{ | |
return $snapshotCopyStatus | |
} | |
} | |
End | |
{ | |
} | |
} | |
<# | |
.Synopsis | |
Get AWS EC2 Snapshots by Name | |
.EXAMPLE | |
Example of how to use this cmdlet | |
.EXAMPLE | |
Another example of how to use this cmdlet | |
#> | |
function get-EC2VolumeSnapshotByName | |
{ | |
[CmdletBinding( | |
SupportsShouldProcess=$true, | |
ConfirmImpact='Low')] | |
[OutputType([String])] | |
Param | |
( | |
# EC2 Region to search for snapshot | |
[Parameter(Mandatory=$true, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=0)] | |
[ValidateNotNullOrEmpty()] | |
[Alias("EC2Region", "SnapshotRegion")] | |
[string]$region, | |
# Snapshot Name to search for | |
[Parameter(Mandatory=$true, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=1)] | |
[ValidateNotNullOrEmpty()] | |
[Alias( "Snapshot Name", "name")] | |
[string]$snapshotName, | |
# Exclude snapshots taken earlier than this date | |
[Parameter(Mandatory=$false, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=2)] | |
[DateTime]$startDate, | |
# Exclude snapshots taken later than this date | |
[ValidateNotNullOrEmpty()] | |
[Parameter(Mandatory=$false, | |
ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
ValueFromRemainingArguments=$false, | |
Position=3)] | |
[DateTime]$endDate | |
) | |
Begin | |
{ | |
# Check the AWS module is loaded | |
if(!(Get-Module | ?{$_.Name -eq "AWSPowerShell"})){ | |
# Check the AWS module is installed | |
if(Get-Module -ListAvailable | ?{$_.name -eq "AWSPowerShell"}){ | |
# Import AWS module | |
Import-Module AWSPowerShell | |
}else{ | |
Throw "Please install the AWS module."; | |
} | |
} | |
# Check we've got AWS creds loaded | |
if(!(Get-AWSCredentials -ListStoredCredentials)){ | |
Throw "No AWS credentials loaded. Use Set-AWSCredentials or Initialize-AWSDefaults to set credentials."; | |
} | |
} | |
Process | |
{ | |
# Create name filter | |
$nameFilter = New-Object Amazon.EC2.Model.Filter | |
$nameFilter.Name = "tag:Name" | |
$nameFilter.Value.Add($snapshotName) | |
# Get Snapshots | |
$snapshots = get-EC2Snapshot -Filter $nameFilter -Region $region | |
# Filter by StartDate | |
if($startDate){ | |
Write-Verbose "Excluding snapshots taken earlier than $startDate"; | |
$snapshots = $snapshots | ?{[DateTime]::Compare($_.StartTime, $startDate) -gt 0} | |
} | |
# Filter by EndDate | |
if($endDate){ | |
Write-Verbose "Excluding snapshots taken later than $endDate"; | |
$snapshots = $snapshots | ?{[DateTime]::Compare($_.StartTime, $endDate) -lt 0} | |
} | |
Write-Output $snapshots | |
} | |
End | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment