From 7f576135fc635c5e19e0f99901d5bd1e60dff305 Mon Sep 17 00:00:00 2001 From: Kevin Woley Date: Thu, 13 Feb 2020 22:58:13 -0800 Subject: [PATCH 1/2] config points for disabling maintenance, email --- backup.ps1 | 17 +++++++++++++++-- config.ps1 | 11 +++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/backup.ps1 b/backup.ps1 index 8b3b437..234f3a7 100644 --- a/backup.ps1 +++ b/backup.ps1 @@ -45,6 +45,12 @@ function Invoke-Unlock { function Invoke-Maintenance { Param($SuccessLog, $ErrorLog) + # skip maintenance if disabled + if($SnapshotMaintenanceEnabled -eq $false) { + Write-Output "[[Maintenance]] Skipped - maintenance disabled" | Tee-Object -Append $SuccessLog + return + } + # skip maintenance if it's been done recently if(($null -ne $ResticStateLastMaintenance) -and ($null -ne $ResticStateMaintenanceCounter)) { $Script:ResticStateMaintenanceCounter += 1 @@ -129,6 +135,10 @@ function Invoke-Backup { $ShadowPath = Join-Path $item.Key 'resticVSS' # Create a symbolic link to the shadow copy + if(Test-Path $ShadowPath) { + Write-Output "[[Backup]] VSS directory exists: '$ShadowPath' - removing. Past script failure?" | Tee-Object -Append $ErrorLog | Tee-Object -Append $SuccessLog + cmd /c rmdir $ShadowPath + } cmd /c mklink /d $ShadowPath "$device" 3>&1 2>> $ErrorLog | Tee-Object -Append $SuccessLog # Build the new list of folders @@ -192,8 +202,10 @@ function Send-Email { $attachments = @{Attachments = $ErrorLog} $status = "ERROR" } - $subject = "$env:COMPUTERNAME Restic Backup Report [$status]" - Send-MailMessage @ResticEmailConfig -From $ResticEmailFrom -To $ResticEmailTo -Credential $credentials -Subject $subject -Body $body @attachments + if((($status -eq "SUCCESS") -and ($SendEmailOnSuccess -ne $false)) -or (($status -eq "ERROR") -and ($SendEmailOnError -ne $false))) { + $subject = "$env:COMPUTERNAME Restic Backup Report [$status]" + Send-MailMessage @ResticEmailConfig -From $ResticEmailFrom -To $ResticEmailTo -Credential $credentials -Subject $subject -Body $body @attachments + } } function Invoke-ConnectivityCheck { @@ -294,6 +306,7 @@ function Invoke-Main { Write-Output "Something went wrong. Sleeping for 15 min and then retrying..." | Tee-Object -Append $success_log if($internet_available -eq $true) { + Invoke-HistoryCheck $success_log $error_log Send-Email $success_log $error_log } Start-Sleep (15*60) diff --git a/config.ps1 b/config.ps1 index 6911e74..72d3e35 100644 --- a/config.ps1 +++ b/config.ps1 @@ -7,12 +7,19 @@ $WindowsExcludeFile = Join-Path $InstallPath "windows.exclude" $LocalExcludeFile = Join-Path $InstallPath "local.exclude" $LogPath = Join-Path $InstallPath "logs" $LogRetentionDays = 30 +$InternetTestAttempts = 10 +$GlobalRetryAttempts = 4 + +# maintenance configuration +$SnapshotMaintenanceEnabled = $true $SnapshotRetentionPolicy = @("--keep-daily", "30", "--keep-weekly", "52", "--keep-monthly", "24", "--keep-yearly", "10") $SnapshotMaintenanceInterval = 7 $SnapshotMaintenanceDays = 30 $SnapshotDeepMaintenanceDays = 90; -$InternetTestAttempts = 10 -$GlobalRetryAttempts = 4 + +# email configuration +$SendEmailOnSuccess = $false +$SendEmailOnError = $true # Paths to backup $BackupSources = @{} From 0334de55460b8297ba1da2fa1182b83c16cb0e63 Mon Sep 17 00:00:00 2001 From: Kevin Woley Date: Thu, 13 Feb 2020 23:04:46 -0800 Subject: [PATCH 2/2] bug fix: previous shadow copy could be backed up If the previous run of the script were aborted, the shadow copy would be left aroudn and then backed up. --- backup.ps1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/backup.ps1 b/backup.ps1 index 234f3a7..8dd1c91 100644 --- a/backup.ps1 +++ b/backup.ps1 @@ -127,18 +127,20 @@ function Invoke-Backup { $starting_location = Get-Location ForEach ($item in $BackupSources.GetEnumerator()) { - # Create the Shadow Copy - $s1 = (Get-WmiObject -List Win32_ShadowCopy).Create($item.Key, "ClientAccessible") - $s2 = Get-WmiObject -Class Win32_ShadowCopy | Where-Object { $_.ID -eq $s1.ShadowID } - - $device = $s2.DeviceObject + "\" $ShadowPath = Join-Path $item.Key 'resticVSS' - - # Create a symbolic link to the shadow copy + + # check for existance of previous, orphaned VSS directory (and remove it) before creating the shadow copy if(Test-Path $ShadowPath) { Write-Output "[[Backup]] VSS directory exists: '$ShadowPath' - removing. Past script failure?" | Tee-Object -Append $ErrorLog | Tee-Object -Append $SuccessLog cmd /c rmdir $ShadowPath } + + # Create the shadow copy + $s1 = (Get-WmiObject -List Win32_ShadowCopy).Create($item.Key, "ClientAccessible") + $s2 = Get-WmiObject -Class Win32_ShadowCopy | Where-Object { $_.ID -eq $s1.ShadowID } + + # Create a symbolic link to the shadow copy + $device = $s2.DeviceObject + "\" cmd /c mklink /d $ShadowPath "$device" 3>&1 2>> $ErrorLog | Tee-Object -Append $SuccessLog # Build the new list of folders