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