Skip to content

Instantly share code, notes, and snippets.

@seanbamforth
Created March 8, 2014 18:41
Show Gist options
  • Save seanbamforth/9436765 to your computer and use it in GitHub Desktop.
Save seanbamforth/9436765 to your computer and use it in GitHub Desktop.
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