]> git.p6c8.net - dsmonrot.git/blobdiff - dsmonrot.ps1
More precise PowerShell requirement (4.0 or higher)
[dsmonrot.git] / dsmonrot.ps1
index 95508a14fe2b0973cf4fa522eeeb251cd9fbf23e..7012cf197f3b1ff538e5756c5cc37f8cda650daf 100644 (file)
 # Config\r
 \r
 # Path to backup directory\r
 # Config\r
 \r
 # Path to backup directory\r
+# This directory MUST exist, it is not created automatically!\r
 [String]$backupDir = "Z:\"\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
 # Keep backups for this amount of months (excluding the current month),\r
 # -1 for indefinite\r
 [Int32]$keepMonths = 2\r
@@ -21,8 +26,8 @@
 # WARNING: If this option is set to $True and the full backup fails you could\r
 # have NO backup\r
 [Boolean]$rotateBeforeBackup = $False\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
 # 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
 # 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
 # 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
 # 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
 \r
 # Map network share to this drive letter, comment out if you don't want to use it\r
 [String]$smbDrive = "Z"\r
 \r
 # Map network share to this drive letter, comment out if you don't want to use it\r
 [String]$smbDrive = "Z"\r
@@ -71,7 +75,6 @@
 \r
 # End of config\r
 \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
 .Synopsis \r
    Write-Log writes a message to a specified log file with the current time stamp. \r
@@ -188,10 +191,11 @@ function Write-Log
     } \r
 }\r
 \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
 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
                $smtp = New-Object System.Net.Mail.SmtpClient($emailMailServer, $emailPort)\r
 \r
                $smtp.EnableSSL = $emailSSL\r
@@ -227,6 +231,26 @@ function Rotate-Backup {
        }\r
 }\r
 \r
        }\r
 }\r
 \r
+function Rotate-Log {\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
 $dsAdditionalArgs = @("--UseVSS")\r
 \r
 $errorMessages = @()\r
@@ -238,8 +262,9 @@ $dsCommand = ""
 \r
 $currMonth = Get-Date -format "yyyy-MM"\r
 $currDay = Get-Date -format "yyyy-MM-dd"\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
-\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
 if(!(Test-Path $logDir)) {\r
        try {\r
                New-Item -ItemType directory -Path $logDir -ErrorAction Stop | Out-Null\r
@@ -252,10 +277,12 @@ if(!(Test-Path $logDir)) {
 \r
 $logFile = "$logDir\$currMonth.log"\r
 \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
 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
        if($smbDrive) {\r
                Write-Log "Connecting network drive $smbDrive to $smbPath" -Path $logFile\r
 \r
@@ -282,18 +309,29 @@ if($errorMessages.Count -eq 0) {
                }\r
        }\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
        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
        if($errorMessages.Count -eq 0) {\r
+               # Compose the backup target directories\r
                $backupTarget = $backupDir + "\" + $currMonth\r
                $backupTarget = $backupDir + "\" + $currMonth\r
-               $backupTargetFull = $backupTarget + "\" + "Full"\r
+               $backupTargetFull = $backupTarget + "\Full"\r
 \r
 \r
-               $backupTargetDiff = $backupTarget + "\" + "Diff-" + $currDay\r
+               $backupTargetDiff = $backupTarget + "\Diff-" + $currDay\r
+               \r
+               if($multipleDailyBackups) {\r
+                       $backupTargetDiff = $backupTargetDiff + "-" + $currTime\r
+               }\r
 \r
 \r
+               # Check if the backup target for this month, the directory for the full backup\r
+               # and the hash files exists. In this case we do a differential backup.\r
                if((Test-Path $backupTarget) -and (Test-Path $backupTargetFull) -and (Test-Path "$backupTargetFull\*.hsh")) {\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
                        Write-Log "Doing a differential backup" -Path $logFile\r
                        \r
                        $isDiff = $True\r
@@ -333,6 +371,8 @@ if($errorMessages.Count -eq 0) {
                        }\r
                }\r
                else {\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
                        Write-Log "Doing a full backup" -Path $logFile\r
 \r
                        if(!(Test-Path $backupTarget)) {\r
@@ -387,6 +427,7 @@ if($errorMessages.Count -eq 0) {
                }\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
        if($smbConnected) {\r
                Write-Log "Disconnecting network drive" -Path $logFile\r
                \r
@@ -398,8 +439,12 @@ if($errorMessages.Count -eq 0) {
                        $errorMessages +=  "Could not disconnect network drive $smbDrive`: $_.Exception.Message"\r
                }\r
        }\r
                        $errorMessages +=  "Could not disconnect network drive $smbDrive`: $_.Exception.Message"\r
                }\r
        }\r
+       \r
+       # Rotate the log files\r
+       Rotate-Log\r
 }\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
 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
@@ -411,7 +456,7 @@ if($emailOnError -and $errorMessages.Count -gt 0) {
        $emailBody += "Drive Snapshot command: $dsCommand`n`n"\r
        $emailBody += ($errorMessages -join "`n")\r
 \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
 }\r
 \r
 $endTime = Get-Date -format "yyyy-MM-dd HH:mm:ss"\r

patrick-canterino.de