Skip to content

Instantly share code, notes, and snippets.

@jschlackman
Created November 12, 2023 02:01
Show Gist options
  • Save jschlackman/d407a5a8c0cd686da242b5837f1a3ccd to your computer and use it in GitHub Desktop.
Save jschlackman/d407a5a8c0cd686da242b5837f1a3ccd to your computer and use it in GitHub Desktop.
Runs an external backup executable, logs output, and sends email notifications. This example runs the FastGlacier console application to sync a local folder hierarchy with S3 Glacier storage.
# Name: Start-ExternalBackup.ps1
# Author: James Schlackman
# Last Modified: Nov 11 2023
# Runs an external backup executable, logs output, and sends email notifications.
Param(
# External backup executable
[Parameter()] [String] $BackupExe = "$env:ProgramFiles\FastGlacier\glacier-con.exe",
# Backup job arguments to pass to executable
[Parameter()] [String] $JobArgs = 'glacier-con.exe sync my-account "e:\my videos" eu-west-1 "vault-3/my videos" ncds',
# Path to store output logs
[Parameter()] [String] $LogPath = 'e:\logs\',
# Backup job name for log files and email report
[Parameter()] [String] $JobName = 'Main Backup'
)
$LogName = "$(Get-Date -Format yyMMdd-HHmm) $JobName"
# Configure mail relay and destination
$MailRelay = 'smtp.gmail.com'
$MailRelayPort = 587
$MailUserName = 'myemailaddress@gmail.com'
# Encrypted password file, generate using ConvertFrom-SecureString (Read-Host -AsSecureString)
$MailPassFile = 'C:\Users\Me\mailapppassword.enc'
$FromAddress = "$JobName <myemailaddress@gmail.com>"
$ToAddress = 'myemailaddress@gmail.com'
# Setup email styles and footer
$ReportHead = "<html><head><style>body {font-family: Calibri,sans-serif; font-size: 11pt} h1 {font-family: Segoe UI Light,sans-serif} p.footer {margin-top: 3em; font-size: 9pt; font-style: italic; color: gray} table {background-color: #e6e6e6} td,th {background-color: white; padding: 3px} th {background-color: #f2f2f2}</style></head><body>"
$ReportFooter = "<p class=""footer"">This is a scripted message sent via the Task Scheduler on $env:COMPUTERNAME.</p></body></html>"
# Check executable exists
If (Test-Path $BackupExe) {
Write-Host "$(Get-Date) - Starting backup job..."
# Run the backup job
$BackupJob = Start-Process -FilePath $BackupExe -NoNewWindow -ArgumentList $JobArgs -RedirectStandardOutput "$LogPath$LogName.log" -PassThru
# Get some info on the backup tool for reporting
$BackupDesc = ''
If ([bool]$BackupJob.Description) {
$BackupDesc += "<tr><th>Backup tool</th><td>$($BackupJob.Description)</td></tr>"
}
If ([bool]$BackupJob.FileVersion) {
$BackupDesc += "<tr><th>Version</th><td>$($BackupJob.FileVersion)</td></tr>"
}
# Wait for backup job to finish
$BackupJob | Wait-Process
# Check if job completed without errors
If ($BackupJob.ExitCode -eq 0) {
$ReportTitle = "$JobName completed"
$ErrorOutput = ''
} Else {
$ReportTitle = "$JobName completed with errors"
$ErrorOutput = "<tr><th>Exit code</th><td>$($BackupJob.ExitCode)</td></tr>"
}
Write-Host "$(Get-Date) - Backup job complete."
If (Test-Path "$LogPath$LogName.log") {
# Zip the log file
Compress-Archive -Path "$LogPath$LogName.log" -DestinationPath "$LogPath$LogName.zip"
# Delete the raw log file once zipped
If (Test-Path "$LogPath$LogName.zip") {
Write-Host 'Log file archived: ' -NoNewline
Write-Host "$LogPath$LogName.zip" -ForegroundColor Cyan
Remove-Item "$LogPath$LogName.log"
} Else {
Write-Host 'Log file saved: ' -NoNewline
Write-Host "$LogPath$LogName.log" -ForegroundColor Cyan
}
} Else {
Write-Host 'Unable to save log file: ' -NoNewline
Write-Host "$LogPath$LogName.log" -ForegroundColor Red
}
# Remove logs more than 30 days old
$OldLogs = Get-ChildItem -Path $LogPath | Where-Object -Property LastWriteTime -lt (Get-Date).AddDays(-30)
$OldLogs | Remove-Item
# Build report
$ReportBody = @"
<h1>Report: $ReportTitle</h1>
<p>A full log can be located at <span style="font-family: monospace">$LogPath$LogName.zip</span></p>
<table>
$BackupDesc
<tr><th>Executable path</th><td style="font-family: monospace">$BackupExe</td></tr>
<tr><th>Job parameters</th><td style="font-family: monospace">$JobArgs</td></tr>
<tr><th>Start Time</th><td>$($BackupJob.StartTime)</td></tr>
<tr><th>End Time</th><td>$($BackupJob.ExitTime)</td></tr>
$ErrorOutput
</table>
"@
} Else {
$ReportTitle = "$JobName failed to start"
$ReportBody = "<h1>Report: $ReportTitle</h1><p>Backup executable could not be located at <span style=""font-family: monospace"">$BackupExe</span></p>"
}
# Send report by email
If ($MailRelay) {
If (Test-Path $MailPassFile) {
# Build credentials using password file
$MailCred = New-Object System.Management.Automation.PSCredential ($MailUserName, (ConvertTo-SecureString -String (Get-Content -Path $MailPassFile)))
}
Send-MailMessage -SmtpServer $MailRelay -Port $MailRelayPort -Credential $MailCred -UseSsl -Subject $ReportTitle -From $FromAddress -To $ToAddress -Encoding UTF8 `
-BodyAsHtml "$ReportHead$ReportBody$ReportFooter"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment