]> git.p6c8.net - dsmonrot.git/blob - dsmonrot.ps1
First version of the script
[dsmonrot.git] / dsmonrot.ps1
1 # DSMonRot
2 # Script for rotating Drive Snapshot backups monthly
3 #
4 # Author: Patrick Canterino <patrick@patrick-canterino.de>
5 # WWW: https://www.patrick-canterino.de/
6 # https://github.com/pcanterino/dsmonrot/
7 # License: 2-Clause BSD License
8 #
9 # Drive Snapshot is copyright by Tom Ehlert
10 # http://www.drivesnapshot.de/
11
12 # Config
13
14 # Path to backup directory
15 [String]$backupDir = "Z:\"
16 # Keep backup for this amount of months (excluding the current month), -1 for indefinite
17 [Int32]$keepMonths = 2
18 # Path to Drive Snapshot
19 [String]$dsPath = "C:\Users\Patrick\Desktop\DSMonRot\snapshot.exe"
20 # Path to Drive Snapshot log file
21 [String]$dsLogFile = "C:\Users\Patrick\Desktop\DSMonRot\snapshot.log"
22 # Disks to backup, see http://www.drivesnapshot.de/en/commandline.htm
23 [String]$disksToBackup = "HD1:1"
24 # Path to DSMonRot log file
25 [String]$logFile = "C:\Users\Patrick\Desktop\DSMonRot\dsmonrot.log"
26
27 # Map network share to this drive letter, comment out if you don't want to use it
28 [String]$smbDrive = "Z"
29 # Path to network share
30 [String]$smbPath = "\\192.168.0.3\ds"
31 # User and password for connecting to network share, comment out if you don't want to use it
32 # (for example if you want to pass current Windows credentials)
33 [String]$smbUser = "patrick"
34 [String]$smbPassword = ""
35
36 # Send an email if an error occured
37 [Boolean]$emailOnError = $True
38 # From address of email notification
39 [String]$emailFromAddress = "alarm@test.local"
40 # To address of email notification
41 [String]$emailToAddress = "patrick@test.local"
42 # Subject of email notification
43 [String]$emailSubject = "DSMonRot"
44 # Mail server
45 [String]$emailMailserver = "localhost"
46 # SMTP Port
47 [Int32]$emailPort = 25
48 # Use SSL?
49 [Boolean]$emailSSL = $False
50 # Use SMTP Auth?
51 [Boolean]$emailAuth = $False
52 # SMTP Auth User
53 [String]$emailUser = ""
54 # SMTP Auth Password
55 [String]$emailPassword = ""
56
57 # End of config
58
59 $dsAdditionalArgs = @("--logfile:$dsLogFile", "--UseVSS")
60
61 # Allow SMTP with SSL and SMTP Auth
62 # see: http://petermorrissey.blogspot.de/2013/01/sending-smtp-emails-with-powershell.html
63 function Send-Email([String]$body) {
64 Write-Host "Sending email: $emailToAddress, $body"
65
66 try {
67 $smtp = New-Object System.Net.Mail.SmtpClient($emailMailServer, $emailPort);
68
69 $smtp.EnableSSL = $emailSSL
70
71 if($emailAuth) {
72 $smtp.Credentials = New-Object System.Net.NetworkCredential($emailUser, $emailPassword);
73 }
74
75 $smtp.Send($emailFromAddress, $emailToAddress, $emailSubject, $body);
76 }
77 catch {
78 Write-Host "Could not send email: $_.Exception.Message"
79 }
80 }
81
82 $errorMessages = @()
83
84 $smbConnected = $False
85 $success = $False
86
87 if($smbDrive) {
88 Try {
89 Write-Host "Connecting network drive"
90
91 if($smbUser -and $smbPassword) {
92 Write-Host "With credentials"
93
94 $secSmbPassword = $smbPassword | ConvertTo-SecureString -asPlainText -Force
95 $smbCredential = New-Object System.Management.Automation.PSCredential($smbUser, $secSmbPassword)
96
97 New-PSDrive -Name $smbDrive -PSProvider "FileSystem" -Root $smbPath -Credential $smbCredential -Persist -ErrorAction Stop
98 #net use "$smbDrive`:" $smbPath $smbPassword /user:$smbUser
99 }
100 else {
101 Write-Host "Without credentials"
102
103 New-PSDrive -Name $smbDrive -PSProvider "FileSystem" -Root $smbPath -Persist -ErrorAction Stop
104 #net use "$smbDrive`:" $smbPath
105 }
106
107 $smbConnected = $True
108 }
109 Catch {
110 Write-Host "Could not connect to network drive: $_.Exception.Message"
111 exit
112 }
113 }
114
115 if(!(Test-Path $backupDir)) {
116 Write-Host "Directory $backupDir does not exist!"
117 exit
118 }
119
120 $currMonth = Get-Date -format "yyyy-MM"
121 $currDay = Get-Date -format "yyyy-MM-dd"
122
123 Write-Host $currMonth
124
125 $backupTarget = $backupDir + "\" + $currMonth
126 $backupTargetFull = $backupTarget + "\" + "Full"
127
128 $backupTargetDiff = $backupTarget + "\" + "Diff-" + $currDay
129
130 Write-Host $backupTarget
131
132 $isDiff = $False
133
134 if((Test-Path $backupTarget) -and (Test-Path $backupTargetFull) -and (Test-Path "$backupTargetFull\*.hsh")) {
135 Write-Host "Differential backup"
136
137 $isDiff = $True
138
139 if(!(Test-Path $backupTargetDiff)) {
140 Write-Host "Creating directory $backupTargetDiff"
141
142 try {
143 New-Item -ItemType directory -Path $backupTargetDiff -ErrorAction Stop
144
145 $success = $True
146 }
147 catch {
148 Write-Host "Could not create directory $backupTargetDiff`: $_.Exception.Message"
149 exit
150 }
151
152 $dsArgs = @($disksToBackup, "$backupTargetFull\`$disk.sna", "-h$backupTargetFull\`$disk.hsh") + $dsAdditionalArgs
153 Write-Host $dsPath ($dsArgs -join " ")
154
155 & $dsPath $dsArgs
156
157 if($LastExitCode -ne 0) {
158 Write-Host "Error code: $LastExitCode"
159 }
160 }
161 else {
162 Write-Host "Directory $backupTargetDiff already exists!"
163
164 $errorMessages += "Directory $backupTargetDiff already exists!"
165 }
166 }
167 else {
168 Write-Host "Full backup"
169
170 if(!(Test-Path $backupTarget)) {
171 Write-Host "Creating directory $backupTarget"
172 New-Item -ItemType directory -Path $backupTarget
173 }
174
175 if(!(Test-Path $backupTargetFull)) {
176 Write-Host "Creating directory $backupTargetFull"
177 New-Item -ItemType directory -Path $backupTargetFull
178 }
179
180 $dsArgs = @($disksToBackup, "$backupTargetFull\`$disk.sna") + $dsAdditionalArgs
181 Write-Host $dsPath ($dsArgs -join " ")
182
183 & $dsPath $dsArgs
184
185 if($LastExitCode -ne 0) {
186 Write-Host "Error code: $LastExitCode"
187 }
188
189 $success = $False
190 }
191
192 if($isDiff -eq $False -and $success -eq $True -and $keepMonths -ge 0) {
193 Write-Host "Rotating"
194
195 $keepMonthsCount = $keepMonths
196
197 Get-ChildItem $backupDir -Directory | Where-Object {($_.Name -ne $currMonth) -and ($_.Name -match "^\d{4,}-\d{2}$")} | Sort-Object -Descending |
198 Foreach-Object {
199 Write-Host $_ "=>" $_.FullName
200
201 if($keepMonthsCount -ge 0) {
202 $keepMonthsCount--
203 }
204
205 Write-Host $keepMonthsCount
206
207 if($keepMonthsCount -eq -1) {
208 Write-Host "Deleting $_"
209 Remove-Item -Recurse -Force $_.FullName
210 }
211 }
212 }
213
214 if($smbConnected) {
215 Write-Host "Disconnecting network drive"
216 Remove-PSDrive $smbDrive
217 #net use "$smbDrive`:" /delete
218 }
219
220 if($emailOnError -and $errorMessages.Count -gt 0) {
221 Send-Email ("Error:`n"+($errorMessages -join "`n"))
222 }

patrick-canterino.de