]> git.p6c8.net - dsmonrot.git/blobdiff - dsmonrot.ps1
Updated TODO
[dsmonrot.git] / dsmonrot.ps1
index b07d5ef3722452bc3f0f87f366d3d710fdd26c2e..ffe4f461f7da51b1e8a3dd297d2bb4753772cd87 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
-# Keep backup for this amount of months (excluding the current month),\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
 # Rotate BEFORE the beginning of a full backup (default is after a successful\r
 # full backup)\r
 # -1 for indefinite\r
 [Int32]$keepMonths = 2\r
 # Rotate BEFORE the beginning of a full backup (default is after a successful\r
 # full backup)\r
-# WARNING: If this option is set to $True and the full backup fails you have\r
-# NO backup\r
-$rotateBeforeBackup = $False\r
-# Path to Drive Snapshot\r
-[String]$dsPath = "C:\Users\Patrick\Desktop\DSMonRot\snapshot.exe"\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
+# 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
@@ -30,10 +35,17 @@ $rotateBeforeBackup = $False
 # 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 DSMonRot log file\r
-[String]$logFile = "C:\Users\Patrick\Desktop\DSMonRot\dsmonrot.log"\r
+# Path to directory where DSMonRot stores the log files\r
+# Every month a new log file is created\r
+[String]$logDir = "$PSScriptRoot\log"\r
+# Keep log files for this amount of months (excluding the current month),\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
 # Map network share to this drive letter, comment out if you don't want to use it\r
 [String]$smbDrive = "Z"\r
@@ -67,14 +79,127 @@ $rotateBeforeBackup = $False
 \r
 # End of config\r
 \r
 \r
 # End of config\r
 \r
-$dsAdditionalArgs = @("--UseVSS")\r
+<# \r
+.Synopsis \r
+   Write-Log writes a message to a specified log file with the current time stamp. \r
+.DESCRIPTION \r
+   The Write-Log function is designed to add logging capability to other scripts. \r
+   In addition to writing output and/or verbose you can write to a log file for \r
+   later debugging. \r
+.NOTES \r
+   Created by: Jason Wasser @wasserja \r
+   Modified: 11/24/2015 09:30:19 AM   \r
\r
+   Changelog: \r
+    * Code simplification and clarification - thanks to @juneb_get_help \r
+    * Added documentation. \r
+    * Renamed LogPath parameter to Path to keep it standard - thanks to @JeffHicks \r
+    * Revised the Force switch to work as it should - thanks to @JeffHicks \r
\r
+   To Do: \r
+    * Add error handling if trying to create a log file in a inaccessible location. \r
+    * Add ability to write $Message to $Verbose or $Error pipelines to eliminate \r
+      duplicates. \r
+.PARAMETER Message \r
+   Message is the content that you wish to add to the log file.  \r
+.PARAMETER Path \r
+   The path to the log file to which you would like to write. By default the function will  \r
+   create the path and file if it does not exist.  \r
+.PARAMETER Level \r
+   Specify the criticality of the log information being written to the log (i.e. Error, Warning, Informational) \r
+.PARAMETER NoClobber \r
+   Use NoClobber if you do not wish to overwrite an existing file. \r
+.EXAMPLE \r
+   Write-Log -Message 'Log message'  \r
+   Writes the message to c:\Logs\PowerShellLog.log. \r
+.EXAMPLE \r
+   Write-Log -Message 'Restarting Server.' -Path c:\Logs\Scriptoutput.log \r
+   Writes the content to the specified log file and creates the path and file specified.  \r
+.EXAMPLE \r
+   Write-Log -Message 'Folder does not exist.' -Path c:\Logs\Script.log -Level Error \r
+   Writes the message to the specified log file as an error message, and writes the message to the error pipeline. \r
+.LINK \r
+   https://gallery.technet.microsoft.com/scriptcenter/Write-Log-PowerShell-999c32d0 \r
+#>\r
+function Write-Log \r
+{ \r
+    [CmdletBinding()] \r
+    Param \r
+    ( \r
+        [Parameter(Mandatory=$true, \r
+                   ValueFromPipelineByPropertyName=$true)] \r
+        [ValidateNotNullOrEmpty()] \r
+        [Alias("LogContent")] \r
+        [string]$Message, \r
\r
+        [Parameter(Mandatory=$false)] \r
+        [Alias('LogPath')] \r
+        [string]$Path='C:\Logs\PowerShellLog.log', \r
+         \r
+        [Parameter(Mandatory=$false)] \r
+        [ValidateSet("Error","Warn","Info")] \r
+        [string]$Level="Info", \r
+         \r
+        [Parameter(Mandatory=$false)] \r
+        [switch]$NoClobber \r
+    ) \r
\r
+    Begin \r
+    { \r
+        # Set VerbosePreference to Continue so that verbose messages are displayed. \r
+        $VerbosePreference = 'Continue' \r
+    } \r
+    Process \r
+    { \r
+         \r
+        # If the file already exists and NoClobber was specified, do not write to the log. \r
+        if ((Test-Path $Path) -AND $NoClobber) { \r
+            Write-Error "Log file $Path already exists, and you specified NoClobber. Either delete the file or specify a different name." \r
+            Return \r
+            } \r
\r
+        # If attempting to write to a log file in a folder/path that doesn't exist create the file including the path. \r
+        elseif (!(Test-Path $Path)) { \r
+            Write-Verbose "Creating $Path." \r
+            $NewLogFile = New-Item $Path -Force -ItemType File \r
+            } \r
\r
+        else { \r
+            # Nothing to see here yet. \r
+            } \r
\r
+        # Format Date for our Log File \r
+        $FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" \r
\r
+        # Write message to error, warning, or verbose pipeline and specify $LevelText \r
+        switch ($Level) { \r
+            'Error' { \r
+                Write-Error $Message \r
+                $LevelText = 'ERROR:' \r
+                } \r
+            'Warn' { \r
+                Write-Warning $Message \r
+                $LevelText = 'WARNING:' \r
+                } \r
+            'Info' { \r
+                Write-Verbose $Message \r
+                $LevelText = 'INFO:' \r
+                } \r
+            } \r
+         \r
+        # Write log entry to $Path \r
+        "$FormattedDate $LevelText $Message" | Out-File -FilePath $Path -Append \r
+    } \r
+    End \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
 function Send-Email([String]$body) {\r
-       Write-Host "Sending email: $emailToAddress, $body"\r
-       \r
        try {\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
@@ -86,175 +211,263 @@ function Send-Email([String]$body) {
                $smtp.Send($emailFromAddress, $emailToAddress, $emailSubject, $body)\r
        }\r
        catch {\r
                $smtp.Send($emailFromAddress, $emailToAddress, $emailSubject, $body)\r
        }\r
        catch {\r
-               Write-Host "Could not send email: $_.Exception.Message"\r
+               Write-Log "Could not send email: $_.Exception.Message" -Path $logFile -Level Error\r
        }\r
 }\r
 \r
        }\r
 }\r
 \r
-function Rotate-Backup {\r
+function Invoke-BackupRotation {\r
        if($keepMonths -lt 0) {\r
                return\r
        }\r
        if($keepMonths -lt 0) {\r
                return\r
        }\r
-\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
        \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
                if($keepMonthsCount -eq -1) {\r
                if($keepMonthsCount -ge 0) {\r
                        $keepMonthsCount--\r
                }\r
                \r
                if($keepMonthsCount -eq -1) {\r
-                       Write-Host "Deleting $_"\r
+                       Write-Log "Deleting backup $($_.FullName)" -Path $logFile -Level Info\r
                        Remove-Item -Recurse -Force $_.FullName\r
                }\r
        }\r
 }\r
 \r
                        Remove-Item -Recurse -Force $_.FullName\r
                }\r
        }\r
 }\r
 \r
-Write-Host "Started at" (Get-Date -format "yyyy-MM-dd HH:mm:ss")\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
 $smbConnected = $False\r
 $success = $False\r
 \r
 $errorMessages = @()\r
 \r
 $smbConnected = $False\r
 $success = $False\r
+$isDiff = $False\r
+$dsCommand = ""\r
 \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
+$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
-                       New-PSDrive -Name $smbDrive -PSProvider "FileSystem" -Root $smbPath -Credential $smbCredential -Persist -ErrorAction Stop\r
-               }\r
-               else {\r
-                       Write-Host "Without credentials"\r
-               \r
-                       New-PSDrive -Name $smbDrive -PSProvider "FileSystem" -Root $smbPath -Persist -ErrorAction Stop\r
-               }\r
-               \r
-               $smbConnected = $True\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
        }\r
-       Catch {\r
-               Write-Host "Could not connect to network drive $smbDrive`: $_.Exception.Message"\r
-               exit\r
+       catch {\r
+               Write-Error "Could not create log directory $logDir`: $_.Exception.Message"\r
+               $errorMessages += "Could not create log directory $logDir`: $_.Exception.Message"\r
        }\r
 }\r
 \r
        }\r
 }\r
 \r
-if(!(Test-Path $backupDir)) {\r
-       Write-Host "Directory $backupDir does not exist!"\r
-       exit\r
-}\r
+$logFile = "$logDir\$currMonth.log"\r
 \r
 \r
-$currMonth = Get-Date -format "yyyy-MM"\r
-$currDay = Get-Date -format "yyyy-MM-dd"\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
 \r
-Write-Host $currMonth\r
+       # Connect the network drive if necessary\r
+       if($smbDrive) {\r
+               Write-Log "Connecting network drive $smbDrive to $smbPath" -Path $logFile\r
 \r
 \r
-$backupTarget = $backupDir + "\" + $currMonth\r
-$backupTargetFull = $backupTarget + "\" + "Full"\r
+               try {\r
+                       if($smbUser -and $smbPassword) {\r
+                               Write-Log "Connecting to network drive with credentials" -Path $logFile\r
+                               \r
+                               $secSmbPassword = $smbPassword | ConvertTo-SecureString -asPlainText -Force\r
+                               $smbCredential = New-Object System.Management.Automation.PSCredential($smbUser, $secSmbPassword)\r
 \r
 \r
-$backupTargetDiff = $backupTarget + "\" + "Diff-" + $currDay\r
+                               New-PSDrive -Name $smbDrive -PSProvider "FileSystem" -Root $smbPath -Credential $smbCredential -Persist -ErrorAction Stop | Out-Null\r
+                       }\r
+                       else {\r
+                               Write-Log "Connecting to network drive without credentials" -Path $logFile\r
+                       \r
+                               New-PSDrive -Name $smbDrive -PSProvider "FileSystem" -Root $smbPath -Persist -ErrorAction Stop | Out-Null\r
+                       }\r
+                       \r
+                       $smbConnected = $True\r
+               }\r
+               catch {\r
+                       Write-Log "Could not connect to network drive $smbDrive`: $_.Exception.Message" -Path $logFile -Level Error\r
+                       $errorMessages += "Could not connect to network drive $smbDrive`: $_.Exception.Message"\r
+               }\r
+       }\r
 \r
 \r
-Write-Host $backupTarget\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
 \r
-$isDiff = $False\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
 \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
+               $backupTargetDiff = $backupTarget + "\Diff-" + $currDay\r
                \r
                \r
-               try {\r
-                       New-Item -ItemType directory -Path $backupTargetDiff -ErrorAction Stop\r
-               \r
-                       $success = $True\r
+               if($multipleDailyBackups) {\r
+                       $backupTargetDiff = $backupTargetDiff + "-" + $currTime\r
                }\r
                }\r
-               catch {\r
-                       Write-Host "Could not create directory $backupTargetDiff`: $_.Exception.Message"\r
-                       exit\r
+\r
+               # Compose the "exclude" parameter if necessary\r
+               if($excludedPaths) {\r
+                       $dsAdditionalArgs += "--exclude:" + $excludedPaths\r
                }\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
                \r
-               $dsLogPath = if($dsLogFileToBackup) { "$backupTargetDiff\$dsLogFile" } else { $dsLogFile }\r
-               \r
-               $dsArgs = @($disksToBackup, "--logfile:$dsLogPath", "$backupTargetDiff\`$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 "Drive Snapshot failed to backup! Exit code: $LastExitCode"\r
-                       $errorMessages += "Drive Snapshot failed to backup! Exit code: $LastExitCode"\r
+                       Write-Log "Doing a differential backup" -Path $logFile\r
+                       \r
+                       $isDiff = $True\r
+                       \r
+                       if(!(Test-Path $backupTargetDiff)) {\r
+                               try {\r
+                                       New-Item -ItemType directory -Path $backupTargetDiff -ErrorAction Stop | Out-Null\r
+                               }\r
+                               catch {\r
+                                       Write-Log "Could not create directory $backupTargetDiff`: $_.Exception.Message" -Path $logFile -Level Error\r
+                                       $errorMessages += "Could not create directory $backupTargetDiff`: $_.Exception.Message"\r
+                               }\r
+                               \r
+                               if($errorMessages.Count -eq 0) {\r
+                                       $dsLogPath = if($dsLogFileToBackup) { "$backupTargetDiff\$dsLogFile" } else { $dsLogFile }\r
+                                       \r
+                                       $dsArgs = @($disksToBackup, "--logfile:$dsLogPath", "$backupTargetDiff\`$disk.sna", "-h$backupTargetFull\`$disk.hsh") + $dsAdditionalArgs\r
+                                       $dsCommand = "$dsPath $dsArgs"\r
+                                       \r
+                                       Write-Log $dsCommand -Path $logFile\r
+                                       \r
+                                       & $dsPath $dsArgs\r
+                                       \r
+                                       if($LastExitCode -ne 0) {\r
+                                               Write-Log "Drive Snapshot failed to backup! Exit code: $LastExitCode" -Path $logFile -Level Error\r
+                                               $errorMessages += "Drive Snapshot failed to backup! Exit code: $LastExitCode"\r
+                                       }\r
+                                       else {\r
+                                               Write-Log "Drive Snapshot succeeded!" -Path $logFile\r
+                                               $success = $True\r
+                                       }\r
+                               }\r
+                       }\r
+                       else {\r
+                               Write-Log "Directory $backupTargetDiff already exists!" -Path $logFile -Level Error\r
+                               $errorMessages += "Directory $backupTargetDiff already exists!"\r
+                       }\r
                }\r
                else {\r
                }\r
                else {\r
-                       $success = $True\r
-               }\r
-       }\r
-       else {\r
-               Write-Host "Directory $backupTargetDiff already exists!"\r
-               $errorMessages += "Directory $backupTargetDiff already exists!"\r
-       }\r
-}\r
-else {\r
-       Write-Host "Full backup"\r
+                       # Do a full backup\r
+               \r
+                       Write-Log "Doing a full backup" -Path $logFile\r
 \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
-       if($rotateBeforeBackup) {\r
-               Rotate-Backup\r
-       }\r
-       \r
-       $dsLogPath = if($dsLogFileToBackup) { "$backupTargetFull\$dsLogFile" } else { $dsLogFile }\r
+                       if(!(Test-Path $backupTarget)) {\r
+                               try {\r
+                                       New-Item -ItemType directory -Path $backupTarget -ErrorAction Stop | Out-Null\r
+                               }\r
+                               catch {\r
+                                       Write-Log "Could not create directory $backupTarget`: $_.Exception.Message" -Path $logFile -Level Error\r
+                                       $errorMessages += "Could not create directory $backupTarget`: $_.Exception.Message"\r
+                               }\r
+                       }\r
+                       \r
+                       if($errorMessages.Count -eq 0) {\r
+                               if(!(Test-Path $backupTargetFull)) {\r
+                                       try {\r
+                                               New-Item -ItemType directory -Path $backupTargetFull -ErrorAction Stop | Out-Null\r
+                                       }\r
+                                       catch {\r
+                                               Write-Log "Could not create directory $backupTargetFull`: $_.Exception.Message" -Path $logFile -Level Error\r
+                                               $errorMessages += "Could not create directory $backupTargetFull`: $_.Exception.Message"\r
+                                       }\r
+                               }\r
+                               \r
+                               if($errorMessages.Count -eq 0) {\r
+                                       if($rotateBeforeBackup) {\r
+                                               Invoke-BackupRotation\r
+                                       }\r
+                                       \r
+                                       $dsLogPath = if($dsLogFileToBackup) { "$backupTargetFull\$dsLogFile" } else { $dsLogFile }\r
 \r
 \r
-       $dsArgs = @($disksToBackup, "--logfile:$dsLogPath", "$backupTargetFull\`$disk.sna") + $dsAdditionalArgs\r
-       Write-Host $dsPath ($dsArgs -join " ")\r
-       \r
-       & $dsPath $dsArgs\r
-       \r
-       if($LastExitCode -ne 0) {\r
-               Write-Host "Drive Snapshot failed to backup! Exit code: $LastExitCode"\r
-               $errorMessages += "Drive Snapshot failed to backup! Exit code: $LastExitCode"\r
+                                       $dsArgs = @($disksToBackup, "--logfile:$dsLogPath", "$backupTargetFull\`$disk.sna") + $dsAdditionalArgs\r
+                                       $dsCommand = "$dsPath $dsArgs"\r
+                                       \r
+                                       Write-Log $dsCommand -Path $logFile\r
+                                       \r
+                                       & $dsPath $dsArgs\r
+                                       \r
+                                       if($LastExitCode -ne 0) {\r
+                                               Write-Log "Drive Snapshot failed to backup! Exit code: $LastExitCode" -Path $logFile -Level Error\r
+                                               $errorMessages += "Drive Snapshot failed to backup! Exit code: $LastExitCode"\r
+                                       }\r
+                                       else {\r
+                                               Write-Log "Drive Snapshot succeeded!" -Path $logFile\r
+                                               $success = $True\r
+                                       }\r
+                                       \r
+                                       if($rotateBeforeBackup -eq $False -and $success -eq $True) {\r
+                                               Invoke-BackupRotation\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
        }\r
        }\r
-       else {\r
-               $success = $True\r
+\r
+       # Disconnect the network drive if necessary\r
+       if($smbConnected) {\r
+               Write-Log "Disconnecting network drive" -Path $logFile\r
+               \r
+               try {\r
+                       Remove-PSDrive $smbDrive -ErrorAction Stop\r
+               }\r
+               catch {\r
+                       Write-Log "Could not disconnect network drive $smbDrive`: $_.Exception.Message" -Path $logFile -Level Error\r
+                       $errorMessages +=  "Could not disconnect network drive $smbDrive`: $_.Exception.Message"\r
+               }\r
        }\r
        \r
        }\r
        \r
-       if($rotateBeforeBackup -eq $False -and $success -eq $True) {\r
-               Rotate-Backup\r
-       }\r
-}\r
+       # Rotate the log files\r
+       Invoke-LogRotation\r
 \r
 \r
-if($smbConnected) {\r
-       Write-Host "Disconnecting network drive"\r
-       \r
-       try {\r
-               Remove-PSDrive $smbDrive -ErrorAction Stop\r
-       }\r
-       catch {\r
-               Write-Host "Could not disconnect network drive $smbDrive`: $_.Exception.Message"\r
-               $errorMessages +=  "Could not disconnect network drive $smbDrive`: $_.Exception.Message"\r
-       }\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
 if($emailOnError -and $errorMessages.Count -gt 0) {\r
-       Send-Email ("Error:`n"+($errorMessages -join "`n"))\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 += "Backup directory:       $backupDir`n"\r
+       $emailBody += "Log directory:          $logDir`n"\r
+       $emailBody += "Current log file:       $logFile`n"\r
+       $emailBody += "Differential backup:    $isDiff`n"\r
+       $emailBody += "Backup successful:      $success`n"\r
+       $emailBody += "Drive Snapshot command: $dsCommand`n`n"\r
+       $emailBody += ($errorMessages -join "`n")\r
+\r
+       Send-Email $emailBody\r
 }\r
 \r
 }\r
 \r
-Write-Host "Ended at" (Get-Date -format "yyyy-MM-dd HH:mm:ss")
\ No newline at end of file
+$endTime = Get-Date -format "yyyy-MM-dd HH:mm:ss"\r
+Write-Log "Ended at $endTime" -Path $logFile
\ No newline at end of file

patrick-canterino.de