Created
August 28, 2019 07:42
-
-
Save panicoenlaxbox/5aceff3524f7d0e78de053c2a3318d1b to your computer and use it in GitHub Desktop.
Backup files to AWS S3
This file contains 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( | |
[Parameter(Mandatory = $True)] | |
[string]$RootPath, | |
[Parameter(Mandatory = $True)] | |
[string]$BucketName, | |
[Parameter(Mandatory = $True)] | |
[string]$AccessKey, | |
[Parameter(Mandatory = $True)] | |
[string]$SecretKey, | |
[switch]$RemoveRootPathFromS3Key | |
) | |
# Do not display errors, but add them to the $error collection. | |
$ErrorActionPreference = "SilentlyContinue" | |
# Display errors, but continue execution of the current cmdlet, script, function, or pipeline. This is the default. | |
# $ErrorActionPreference = "Continue" | |
function GetFileExtension { | |
param ( | |
[Parameter(Mandatory = $True)] | |
[string]$Path | |
) | |
[System.IO.Path]::GetExtension($Path) | |
} | |
<# | |
.SYNOPSIS | |
Set file extension | |
.DESCRIPTION | |
Set file extension, append or overwrite | |
.PARAMETER Path | |
File to operate with | |
#> | |
function SetFileExtension { | |
param ( | |
[Parameter(Mandatory = $True)] | |
[string]$Path, | |
[Parameter(Mandatory = $True)] | |
[string]$Extension | |
) | |
if (!$Extension.StartsWith('.')) { | |
$Extension = ".$Extension" | |
} | |
if ($null -eq ([System.IO.Path]::GetExtension($Path))) { | |
$Path + $Extension | |
} | |
else { | |
[System.IO.Path]::Combine( | |
[System.IO.Path]::GetDirectoryName($Path), | |
[System.IO.Path]::GetFileNameWithoutExtension($Path)) + $Extension | |
} | |
} | |
function IsZipFile { | |
param ( | |
[Parameter(Mandatory = $True)] | |
[string]$Path | |
) | |
[System.IO.Path]::GetExtension($Path) -eq '.zip' | |
} | |
<# | |
.SYNOPSIS | |
Create the parameter key for Write-S3Object cmdlet. | |
.DESCRIPTION | |
A parameter key with slashes will create folders in S3 bucket | |
#> | |
function CreateS3Key { | |
param( | |
[Parameter(Mandatory = $True)] | |
[string]$Path | |
) | |
[string]$key = [System.IO.Path]::GetDirectoryName($Path) | |
if ($RemoveRootPathFromS3Key) { | |
$key = $key.Substring($RootPath.Length) | |
} | |
$key = $key.TrimStart('\').Replace('\', '/') | |
$key = "$($env:computername)/$(if($key -ne '') {$key + '/'} else {''})$([System.IO.Path]::GetFileName($Path))" | |
$key | |
} | |
function EnsureFileExtension { | |
param ( | |
[Parameter(Mandatory = $True)] | |
[string]$Path, | |
[Parameter(Mandatory = $True)] | |
[string]$Extension | |
) | |
if (!$Extension.StartsWith('.')) { | |
$Extension = ".$Extension" | |
} | |
if ($null -eq ([System.IO.Path]::GetExtension($Path))) { | |
$Path + $Extension | |
} | |
else { | |
[System.IO.Path]::Combine( | |
[System.IO.Path]::GetDirectoryName($Path), | |
[System.IO.Path]::GetFileNameWithoutExtension($Path)) + $Extension | |
} | |
} | |
function TestLastWriteTimeUtc { | |
param( | |
[Parameter(Mandatory = $True)] | |
[string]$Path, | |
[Parameter(Mandatory = $True)] | |
[DateTime] $LastWriteTimeUtc | |
) | |
$Path = EnsureFileExtension $Path '.zip' | |
$key = CreateS3Key -Path $Path | |
$s3LastWriteTimeUtc = Get-S3ObjectTagSet -BucketName $BucketName -Key $key.TrimStart('/') | Where-Object { $_.Key -eq 'LastWriteTimeUtc' } | Select-Object -ExpandProperty Value | |
if ($null -ne $s3LastWriteTimeUtc) { | |
if ($s3LastWriteTimeUtc -eq $LastWriteTimeUtc.ToString()) { | |
$true | |
return | |
} | |
} | |
$false | |
} | |
function UploadS3File { | |
param ( | |
[Parameter(Mandatory = $True)] | |
[string]$Path, | |
[Parameter(Mandatory = $True)] | |
[datetime]$LastWriteTimeUtc | |
) | |
$key = CreateS3Key -Path $Path | |
"Uploading file $Path with key $key" | |
Write-S3Object -BucketName $BucketName -File $Path -Key $key -TagSet @( @{ Key = 'LastWriteTimeUtc'; Value = $LastWriteTimeUtc.ToString() }) | |
} | |
function ZipFile { | |
param ( | |
[Parameter(Mandatory = $True)] | |
[string]$Path, | |
[Parameter(Mandatory = $True)] | |
[string]$TargetPath | |
) | |
"Compressing file $Path" | |
Compress-Archive -Path $Path -DestinationPath $TargetPath -CompressionLevel Optimal | |
} | |
function DeleteFile { | |
param( | |
[Parameter(Mandatory = $True)] | |
[string]$Path | |
) | |
"Deleting file $Path" | |
Remove-Item -Path $Path | |
} | |
$files = Get-ChildItem $RootPath -Recurse -File -Exclude '*.s3.zip' | |
if ($files.Length -eq 0) { | |
'there are no files that match the search pattern' | |
exit | |
} | |
$profileName = [System.Guid]::NewGuid().ToString() | |
"Saving AWS profile" | |
Set-AWSCredential -AccessKey $AccessKey -SecretKey $SecretKey -StoreAs $profileName | |
"Setting AWS profile" | |
Set-AWSCredential -ProfileName $profileName | |
foreach ($file in $files) { | |
if (IsZipFile $file) { | |
if (TestLastWriteTimeUtc -Path $file.FullName -LastWriteTimeUtc $file.LastWriteTimeUtc) { | |
"Identical LastWriteTimeUtc $LastWriteTimeUtc it's not necessary to upload file $($file.FullName)" | |
} | |
else { | |
UploadS3File -Path $file.FullName -LastWriteTimeUtc $file.LastWriteTimeUtc | |
} | |
} | |
else { | |
$tempFile = (SetFileExtension $file.FullName -Extension "$(GetFileExtension $file.FullName).s3.zip") | |
if (TestLastWriteTimeUtc -Path $tempFile -LastWriteTimeUtc $file.LastWriteTimeUtc) { | |
"Identical LastWriteTimeUtc $LastWriteTimeUtc it's not necessary to upload file $($file.FullName)" | |
} | |
else { | |
ZipFile -Path $file.FullName -TargetPath $tempFile | |
UploadS3File -Path $tempFile -LastWriteTimeUtc $file.LastWriteTimeUtc | |
DeleteFile -Path $tempFile | |
} | |
} | |
} | |
"Removing AWS profile" | |
Remove-AWSCredentialProfile -ProfileName $profileName -Force |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment