Created
March 8, 2014 18:41
-
-
Save seanbamforth/9436765 to your computer and use it in GitHub Desktop.
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
param ( | |
[string]$from = $(get-location).ToString(), | |
[string]$to = "selectcs-backup", | |
[switch]$mirror | |
) | |
#$DebugPreference = "Continue" | |
#todo:if no parameters, then show instructions | |
#todo:mirror option into own function | |
#todo:aws details need to be in the environment. | |
#todo:Copy from & copy to to use the same script. Maybe put it into a module. | |
import-module "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\AWSPowerShell.psd1" | |
add-type -assemblyName "System.Web" | |
$blocksize = (1024*1024*5) | |
$startblocks = (1024*1024*16) | |
$AccessKeyId = (get-item env:aws-access-key-id -erroraction ignore).value | |
$AccessKeySecret = (get-item env:aws-access-key-secret -erroraction ignore).value | |
if ( !($AccessKeyId) -or !($AccessKeySecret)) { | |
$ok = ($AccessKeyId) -or ($AccessKeySecret) | |
Write-Host "AWS Access keys have not been created." | |
Write-Host "===================================================================" | |
Write-Host "To run this script you must create two environment variables called" | |
Write-Host "aws-access-key-id and aws-access-key-secret" | |
Write-Host "--" | |
break | |
} | |
# Regions: us-east-1, us-west-2, us-west-1, eu-west-1, ap-southeast-1 | |
$region = "eu-west-1" | |
$backupFrom = $from | |
$backupTo = $to | |
$backupFrom = $backupFrom.ToLower() | |
$BackupTo = $BackupTo.ToLower() | |
if ($backupFrom[-1] -ne "\") { $backupFrom += "\" } | |
$bucket = $BackupTo.Split(":")[0] | |
$s3folder = $BackupTo.Split(":")[1] | |
if (!($s3folder)) { | |
$s3folder = $env:COMPUTERNAME + "/" | |
$s3folder += $(get-location).ToString() + "/" | |
$s3folder = $s3folder.replace("\\","/").replace(":\","/").replace("\","/") | |
$s3folder = $s3folder.ToLower() | |
} | |
$s3folder = $s3folder.ToLower().replace("\" , "/") | |
if ($s3folder[-1] -ne "/") { $s3folder += "/" } | |
$msg="Copying files from $backupFrom to $BackupTo" | |
Write-Host $msg | |
Write-Host "-" | |
Write-Host "Bucket: $bucket" | |
write-Host "Mirror: $mirror" | |
Write-Host "S3 Folder: $s3folder" | |
Write-Host ("=" * $msg.Length) | |
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider | |
function AmazonEtagHashForFile($filename) { | |
$lines = 0 | |
[byte[]] $binHash = @() | |
$reader = [System.IO.File]::Open($filename,"OPEN","READ") | |
if ((Get-Item $filename).length -gt $startblocks) { | |
$buf = new-object byte[] $blocksize | |
while (($read_len = $reader.Read($buf,0,$buf.length)) -ne 0){ | |
$lines += 1 | |
$binHash += $md5.ComputeHash($buf,0,$read_len) | |
} | |
$binHash=$md5.ComputeHash( $binHash ) | |
} | |
else { | |
$lines = 1 | |
$binHash += $md5.ComputeHash($reader) | |
} | |
$reader.Close() | |
$hash = [System.BitConverter]::ToString( $binHash ) | |
$hash = $hash.Replace("-","").ToLower() | |
if ($lines -gt 1) { | |
$hash = $hash + "-$lines" | |
} | |
return $hash | |
} | |
function s3NameToLocalName($file) { | |
$file = $file.replace($s3Folder,"") | |
$file = $file.replace("/" , "\") | |
$file = [System.Web.HttpUtility]::UrlDecode($file) | |
$file = $backupFrom + $file | |
return $file | |
} | |
function s3BackupFile($file) { | |
if (!$file.PSIsContainer) { | |
$fromFile = $file.fullname.ToLower() | |
$tofile = $file.fullname.ToLower() | |
$tofile = $tofile.replace($backupfrom,"") | |
$tofile = $tofile.replace("\" , "/") | |
$tofile = [System.Web.HttpUtility]::UrlEncode($tofile) | |
$tofile = $tofile.replace("%2f" , "/") | |
$tofile = $s3folder + $tofile | |
$s3file = (Get-S3Object -BucketName $bucket -Key $tofile) | |
if ($s3file -eq $null) { | |
Write-Host "$fromFile -> $tofile (New File)" | |
Write-S3Object -BucketName $bucket -File $fromfile -Key $tofile | |
return | |
} | |
$hash = AmazonEtagHashForFile($fromFile) | |
$etag =$s3file[0].etag.Replace('"',"") | |
if ($etag -ne $hash) { | |
Write-Host("$fromFile -> $tofile (Different)" ) | |
Write-S3Object -BucketName $bucket -File $fromfile -Key $tofile | |
} | |
} | |
} | |
Set-AWSCredentials -AccessKey $AccessKeyId -SecretKey $AccessKeySecret | |
Set-DefaultAWSRegion $region | |
#Mirroring.... | |
if ($mirror) { | |
do { | |
$s3files = (Get-S3Object -Marker $marker -MaxKeys $maxkeys -BucketName $bucket -KeyPrefix $s3Folder ) | |
$s3files | Foreach-Object{ | |
$marker = $_.key | |
$LocalFile = (s3NameToLocalName $_.key) | |
if (!(Test-Path $LocalFile)) { | |
$DeleteAmazonFile = $_.key | |
Write-Host ("Deleting... $DeleteAmazonFile") | |
$response = Remove-S3Object -BucketName $bucket -Key $DeleteAmazonFile -Force | |
} | |
} | |
} while ($s3files.length -eq $maxkeys) | |
} | |
#now we restore | |
$files = Get-ChildItem $BackupFrom -Recurse | |
$files | Foreach-Object{ | |
s3BackupFile $_ | |
} | |
Write-Host("..") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment