# Config\r
\r
# Path to backup directory\r
+# This directory MUST exist, it is not created automatically!\r
[String]$backupDir = "Z:\"\r
+# Disks to backup, see http://www.drivesnapshot.de/en/commandline.htm\r
+[String]$disksToBackup = "HD1:1"\r
+# Path to Drive Snapshot\r
+[String]$dsPath = "C:\Users\Patrick\Desktop\DSMonRot\snapshot.exe"\r
# Keep backups for this amount of months (excluding the current month),\r
# -1 for indefinite\r
[Int32]$keepMonths = 2\r
# WARNING: If this option is set to $True and the full backup fails you could\r
# have NO backup\r
[Boolean]$rotateBeforeBackup = $False\r
-# Path to Drive Snapshot\r
-[String]$dsPath = "C:\Users\Patrick\Desktop\DSMonRot\snapshot.exe"\r
+# Set to $True if you want to allow multiple backups for a day\r
+[Boolean]$multipleDailyBackups = $False\r
# Path to Drive Snapshot log file (specify only the file name if you set\r
# $dsLogFileToBackup to $True)\r
#[String]$dsLogFile = "C:\Users\Patrick\Desktop\DSMonRot\snapshot.log"\r
# Set to $True if you want to put the log file of Drive Snapshot into the same\r
# directory as the backup\r
[Boolean]$dsLogFileToBackup = $True\r
-# Disks to backup, see http://www.drivesnapshot.de/en/commandline.htm\r
-[String]$disksToBackup = "HD1:1"\r
# Path to directory where DSMonRot stores the log files\r
# Every month a new log file is created\r
-[String]$logDir = "C:\Users\Patrick\Desktop\DSMonRot\log"\r
+[String]$logDir = "$PSScriptRoot\log"\r
# Keep log files for this amount of months (excluding the current month),\r
-# 0 for indefinite (currently not available)\r
-[Int32]$keepLogs = 1\r
+# 0 or less for indefinite\r
+# You should set this to at least the same as $keepMonths\r
+[Int32]$keepLogs = 2\r
+# Comma separated lists of files and directories to exclude from the backup\r
+# See http://www.drivesnapshot.de/en/commandline.htm\r
+# Comment out if you don't want to use it\r
+#[String]$excludedPaths = "Path1,Path2"\r
\r
# Map network share to this drive letter, comment out if you don't want to use it\r
[String]$smbDrive = "Z"\r
\r
# End of config\r
\r
-# This function is originally by wasserja at https://gallery.technet.microsoft.com/scriptcenter/Write-Log-PowerShell-999c32d0\r
<# \r
.Synopsis \r
Write-Log writes a message to a specified log file with the current time stamp. \r
} \r
}\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
try {\r
+ # Allow SMTP with SSL and SMTP Auth\r
+ # see: http://petermorrissey.blogspot.de/2013/01/sending-smtp-emails-with-powershell.html\r
+ \r
$smtp = New-Object System.Net.Mail.SmtpClient($emailMailServer, $emailPort)\r
\r
$smtp.EnableSSL = $emailSSL\r
}\r
}\r
\r
-function Rotate-Backup {\r
+function Invoke-BackupRotation {\r
if($keepMonths -lt 0) {\r
return\r
}\r
}\r
}\r
\r
+function Invoke-LogRotation {\r
+ if($keepLogs -le 0) {\r
+ return\r
+ }\r
+ \r
+ $keepLogsCount = $keepLogs\r
+ \r
+ Get-ChildItem $logDir -File | Where-Object {($_.Name -ne "$currMonth.log") -and ($_.Name -match "^\d{4,}-\d{2}\.log$")} | Sort-Object -Descending |\r
+ Foreach-Object {\r
+ if($keepLogsCount -ge 0) {\r
+ $keepLogsCount--\r
+ }\r
+ \r
+ if($keepLogsCount -eq -1) {\r
+ Write-Log "Deleting log file $($_.FullName)" -Path $logFile -Level Info\r
+ Remove-Item -Force $_.FullName\r
+ }\r
+ }\r
+}\r
+\r
$dsAdditionalArgs = @("--UseVSS")\r
\r
$errorMessages = @()\r
\r
$currMonth = Get-Date -format "yyyy-MM"\r
$currDay = Get-Date -format "yyyy-MM-dd"\r
+$currTime = Get-Date -format "HH-mm-ss" # no colon because we need this for a directory name\r
\r
-\r
+# Check if the directory for the log files exists and create it if necessary\r
if(!(Test-Path $logDir)) {\r
try {\r
New-Item -ItemType directory -Path $logDir -ErrorAction Stop | Out-Null\r
\r
$logFile = "$logDir\$currMonth.log"\r
\r
+# Continue only if the log directory exists or if it was created successfully (no error message added)\r
if($errorMessages.Count -eq 0) {\r
$startTime = Get-Date -format "yyyy-MM-dd HH:mm:ss"\r
Write-Log "Started at $startTime" -Path $logFile\r
\r
+ # Connect the network drive if necessary\r
if($smbDrive) {\r
Write-Log "Connecting network drive $smbDrive to $smbPath" -Path $logFile\r
\r
}\r
}\r
\r
+ # Check if the backup directory exists\r
if(!(Test-Path $backupDir)) {\r
Write-Log "Directory $backupDir does not exist!" -Path $logFile -Level Error\r
$errorMessages += "Directory $backupDir does not exist!"\r
}\r
\r
+ # Continue only if no error message was recorded (i.e. backup directory does not exist)\r
if($errorMessages.Count -eq 0) {\r
+ # Compose the backup target directories\r
$backupTarget = $backupDir + "\" + $currMonth\r
- $backupTargetFull = $backupTarget + "\" + "Full"\r
+ $backupTargetFull = $backupTarget + "\Full"\r
+\r
+ $backupTargetDiff = $backupTarget + "\Diff-" + $currDay\r
+ \r
+ if($multipleDailyBackups) {\r
+ $backupTargetDiff = $backupTargetDiff + "-" + $currTime\r
+ }\r
\r
- $backupTargetDiff = $backupTarget + "\" + "Diff-" + $currDay\r
+ # Compose the "exclude" parameter if necessary\r
+ if($excludedPaths) {\r
+ $dsAdditionalArgs += "--exclude:" + $excludedPaths\r
+ }\r
\r
+ # Check if the backup target for this month, the directory for the full backup\r
+ # and the hash files exist. In that case we do a differential backup.\r
if((Test-Path $backupTarget) -and (Test-Path $backupTargetFull) -and (Test-Path "$backupTargetFull\*.hsh")) {\r
+ # Do a differential backup\r
+ \r
Write-Log "Doing a differential backup" -Path $logFile\r
\r
$isDiff = $True\r
}\r
}\r
else {\r
+ # Do a full backup\r
+ \r
Write-Log "Doing a full backup" -Path $logFile\r
\r
if(!(Test-Path $backupTarget)) {\r
\r
if($errorMessages.Count -eq 0) {\r
if($rotateBeforeBackup) {\r
- Rotate-Backup\r
+ Invoke-BackupRotation\r
}\r
\r
$dsLogPath = if($dsLogFileToBackup) { "$backupTargetFull\$dsLogFile" } else { $dsLogFile }\r
}\r
\r
if($rotateBeforeBackup -eq $False -and $success -eq $True) {\r
- Rotate-Backup\r
+ Invoke-BackupRotation\r
}\r
}\r
}\r
}\r
}\r
\r
+ # Disconnect the network drive if necessary\r
if($smbConnected) {\r
Write-Log "Disconnecting network drive" -Path $logFile\r
\r
$errorMessages += "Could not disconnect network drive $smbDrive`: $_.Exception.Message"\r
}\r
}\r
+ \r
+ # Rotate the log files\r
+ Invoke-LogRotation\r
+\r
}\r
\r
+# If there was any error message recorded, send a mail if configured\r
if($emailOnError -and $errorMessages.Count -gt 0) {\r
$emailBody = "This is DSMonRot on $env:computername, started at $startTime.`n"\r
$emailBody += "An error occured while performing a backup. Below are the error messages and some status information.`n`n"\r
$emailBody += "Drive Snapshot command: $dsCommand`n`n"\r
$emailBody += ($errorMessages -join "`n")\r
\r
- Send-Email ($emailBody)\r
+ Send-Email $emailBody\r
}\r
\r
$endTime = Get-Date -format "yyyy-MM-dd HH:mm:ss"\r