Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save panicoenlaxbox/5aceff3524f7d0e78de053c2a3318d1b to your computer and use it in GitHub Desktop.
Save panicoenlaxbox/5aceff3524f7d0e78de053c2a3318d1b to your computer and use it in GitHub Desktop.
Backup files to AWS S3
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