+# DSMonRot\r
+# Script for rotating Drive Snapshot backups monthly\r
+#\r
+# Author: Patrick Canterino <patrick@patrick-canterino.de>\r
+# WWW: https://www.patrick-canterino.de/\r
+# https://github.com/pcanterino/dsmonrot/\r
+# License: 2-Clause BSD License\r
+#\r
+# Drive Snapshot is copyright by Tom Ehlert\r
+# http://www.drivesnapshot.de/\r
+\r
+# Config\r
+\r
+# Path to backup directory\r
+[String]$backupDir = "Z:\"\r
+# Keep backup for this amount of months (excluding the current month), -1 for indefinite\r
+[Int32]$keepMonths = 2\r
+# Path to Drive Snapshot\r
+[String]$dsPath = "C:\Users\Patrick\Desktop\DSMonRot\snapshot.exe"\r
+# Path to Drive Snapshot log file\r
+[String]$dsLogFile = "C:\Users\Patrick\Desktop\DSMonRot\snapshot.log"\r
+# Disks to backup, see http://www.drivesnapshot.de/en/commandline.htm\r
+[String]$disksToBackup = "HD1:1"\r
+# Path to DSMonRot log file\r
+[String]$logFile = "C:\Users\Patrick\Desktop\DSMonRot\dsmonrot.log"\r
+\r
+# Map network share to this drive letter, comment out if you don't want to use it\r
+[String]$smbDrive = "Z"\r
+# Path to network share\r
+[String]$smbPath = "\\192.168.0.3\ds"\r
+# User and password for connecting to network share, comment out if you don't want to use it\r
+# (for example if you want to pass current Windows credentials)\r
+[String]$smbUser = "patrick"\r
+[String]$smbPassword = ""\r
+\r
+# Send an email if an error occured\r
+[Boolean]$emailOnError = $True\r
+# From address of email notification\r
+[String]$emailFromAddress = "alarm@test.local"\r
+# To address of email notification\r
+[String]$emailToAddress = "patrick@test.local"\r
+# Subject of email notification\r
+[String]$emailSubject = "DSMonRot"\r
+# Mail server\r
+[String]$emailMailserver = "localhost"\r
+# SMTP Port\r
+[Int32]$emailPort = 25\r
+# Use SSL?\r
+[Boolean]$emailSSL = $False\r
+# Use SMTP Auth?\r
+[Boolean]$emailAuth = $False\r
+# SMTP Auth User\r
+[String]$emailUser = ""\r
+# SMTP Auth Password\r
+[String]$emailPassword = ""\r
+\r
+# End of config\r
+\r
+$dsAdditionalArgs = @("--logfile:$dsLogFile", "--UseVSS")\r
+\r
+# Allow SMTP with SSL and SMTP Auth\r
+# see: http://petermorrissey.blogspot.de/2013/01/sending-smtp-emails-with-powershell.html\r
+function Send-Email([String]$body) {\r
+ Write-Host "Sending email: $emailToAddress, $body"\r
+ \r
+ try {\r
+ $smtp = New-Object System.Net.Mail.SmtpClient($emailMailServer, $emailPort);\r
+\r
+ $smtp.EnableSSL = $emailSSL\r
+\r
+ if($emailAuth) {\r
+ $smtp.Credentials = New-Object System.Net.NetworkCredential($emailUser, $emailPassword);\r
+ }\r
+\r
+ $smtp.Send($emailFromAddress, $emailToAddress, $emailSubject, $body);\r
+ }\r
+ catch {\r
+ Write-Host "Could not send email: $_.Exception.Message"\r
+ }\r
+}\r
+\r
+$errorMessages = @()\r
+\r
+$smbConnected = $False\r
+$success = $False\r
+\r
+if($smbDrive) {\r
+ Try {\r
+ Write-Host "Connecting network drive"\r
+ \r
+ if($smbUser -and $smbPassword) {\r
+ Write-Host "With credentials"\r
+ \r
+ $secSmbPassword = $smbPassword | ConvertTo-SecureString -asPlainText -Force\r
+ $smbCredential = New-Object System.Management.Automation.PSCredential($smbUser, $secSmbPassword)\r
+\r
+ New-PSDrive -Name $smbDrive -PSProvider "FileSystem" -Root $smbPath -Credential $smbCredential -Persist -ErrorAction Stop\r
+ #net use "$smbDrive`:" $smbPath $smbPassword /user:$smbUser\r
+ }\r
+ else {\r
+ Write-Host "Without credentials"\r
+ \r
+ New-PSDrive -Name $smbDrive -PSProvider "FileSystem" -Root $smbPath -Persist -ErrorAction Stop\r
+ #net use "$smbDrive`:" $smbPath\r
+ }\r
+ \r
+ $smbConnected = $True\r
+ }\r
+ Catch {\r
+ Write-Host "Could not connect to network drive: $_.Exception.Message"\r
+ exit\r
+ }\r
+}\r
+\r
+if(!(Test-Path $backupDir)) {\r
+ Write-Host "Directory $backupDir does not exist!"\r
+ exit\r
+}\r
+\r
+$currMonth = Get-Date -format "yyyy-MM"\r
+$currDay = Get-Date -format "yyyy-MM-dd"\r
+\r
+Write-Host $currMonth\r
+\r
+$backupTarget = $backupDir + "\" + $currMonth\r
+$backupTargetFull = $backupTarget + "\" + "Full"\r
+\r
+$backupTargetDiff = $backupTarget + "\" + "Diff-" + $currDay\r
+\r
+Write-Host $backupTarget\r
+\r
+$isDiff = $False\r
+\r
+if((Test-Path $backupTarget) -and (Test-Path $backupTargetFull) -and (Test-Path "$backupTargetFull\*.hsh")) {\r
+ Write-Host "Differential backup"\r
+ \r
+ $isDiff = $True\r
+ \r
+ if(!(Test-Path $backupTargetDiff)) {\r
+ Write-Host "Creating directory $backupTargetDiff"\r
+ \r
+ try {\r
+ New-Item -ItemType directory -Path $backupTargetDiff -ErrorAction Stop\r
+ \r
+ $success = $True\r
+ }\r
+ catch {\r
+ Write-Host "Could not create directory $backupTargetDiff`: $_.Exception.Message"\r
+ exit\r
+ }\r
+ \r
+ $dsArgs = @($disksToBackup, "$backupTargetFull\`$disk.sna", "-h$backupTargetFull\`$disk.hsh") + $dsAdditionalArgs\r
+ Write-Host $dsPath ($dsArgs -join " ")\r
+ \r
+ & $dsPath $dsArgs\r
+ \r
+ if($LastExitCode -ne 0) {\r
+ Write-Host "Error code: $LastExitCode"\r
+ }\r
+ }\r
+ else {\r
+ Write-Host "Directory $backupTargetDiff already exists!"\r
+ \r
+ $errorMessages += "Directory $backupTargetDiff already exists!"\r
+ }\r
+}\r
+else {\r
+ Write-Host "Full backup"\r
+ \r
+ if(!(Test-Path $backupTarget)) {\r
+ Write-Host "Creating directory $backupTarget"\r
+ New-Item -ItemType directory -Path $backupTarget\r
+ }\r
+ \r
+ if(!(Test-Path $backupTargetFull)) {\r
+ Write-Host "Creating directory $backupTargetFull"\r
+ New-Item -ItemType directory -Path $backupTargetFull\r
+ }\r
+\r
+ $dsArgs = @($disksToBackup, "$backupTargetFull\`$disk.sna") + $dsAdditionalArgs\r
+ Write-Host $dsPath ($dsArgs -join " ")\r
+ \r
+ & $dsPath $dsArgs\r
+ \r
+ if($LastExitCode -ne 0) {\r
+ Write-Host "Error code: $LastExitCode"\r
+ }\r
+ \r
+ $success = $False\r
+}\r
+\r
+if($isDiff -eq $False -and $success -eq $True -and $keepMonths -ge 0) {\r
+ Write-Host "Rotating"\r
+ \r
+ $keepMonthsCount = $keepMonths\r
+ \r
+ Get-ChildItem $backupDir -Directory | Where-Object {($_.Name -ne $currMonth) -and ($_.Name -match "^\d{4,}-\d{2}$")} | Sort-Object -Descending |\r
+ Foreach-Object {\r
+ Write-Host $_ "=>" $_.FullName\r
+ \r
+ if($keepMonthsCount -ge 0) {\r
+ $keepMonthsCount--\r
+ }\r
+ \r
+ Write-Host $keepMonthsCount\r
+ \r
+ if($keepMonthsCount -eq -1) {\r
+ Write-Host "Deleting $_"\r
+ Remove-Item -Recurse -Force $_.FullName\r
+ }\r
+ }\r
+}\r
+\r
+if($smbConnected) {\r
+ Write-Host "Disconnecting network drive"\r
+ Remove-PSDrive $smbDrive\r
+ #net use "$smbDrive`:" /delete\r
+}\r
+\r
+if($emailOnError -and $errorMessages.Count -gt 0) {\r
+ Send-Email ("Error:`n"+($errorMessages -join "`n"))\r
+}
\ No newline at end of file