Advertisement
Guest User

Auto-Backup, SMB Server Simple Backup

a guest
Jul 10th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #
  2. # Samba, Auto-Backup Script
  3. # Useage: Auto-Backup.ps1 -Source "\\SourceServer" -Destination D:\Backups -RetentionPolicy 5 -Incremental $true
  4. # Switches;
  5. #    -Source, Specify the source SMB server where all accessible shares will be backed up.
  6. #    -Destination, Specify the path to store backups. A folder Named "Auto-Backup" will be created here.
  7. #    -RetentionPolicy, Specify a number of days to keep backups for. The default is 3.
  8. #    -Incremental, When $true - only changed and new files will be backed up. A full back will be taken every three days.
  9. #    -SingleBackupPerDay, when $false - the script will be allowed to run multiple times in one day.
  10. #
  11.  
  12. # Default script parameters.
  13. $Incremental = $true
  14. $RetentionPolicy = 3
  15. $SingleBackupPerDay = $true
  16.  
  17. # Set script parameters.
  18. Param(
  19.     [string]$Source,
  20.     [string]$Destination,
  21.     [int]$RetentionPolicy,
  22.     [switch]$Incremental,
  23.     [switch]$SingleBackupPerDay
  24. )
  25.  
  26. # Set global variables
  27. $ScriptStart = Get-Date
  28.  
  29. # Error Count, Counted throughout the script for a clean exit
  30. $Errors = 0
  31.  
  32. if (!(Test-Path -Path $Destination)) {
  33.     try {
  34.         New-Item -ItemType Directory -Path $Destination"\Auto-Backup"
  35.     }
  36.     catch {
  37.         scriptLog("Unable to create / access backup destination")
  38.         $Errors++
  39.         Exit 1
  40.     }
  41. }
  42.  
  43. # Notify if the source or destination has not been configured
  44. if (!($Source) -or !($Destination)) {
  45.     scriptLog("You must specify a source and destination before this script can continue.")
  46.     $Errors++
  47.     Exit 1
  48. }
  49.  
  50. # Test if a backup has already been taken today, stop if it has
  51. if (Test-Path -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))) -and $SingleBackupPerDay = $true) {
  52.     scriptLog("A backup has already been taken today. The script will now terminate.")
  53.     $Errors++
  54.     Exit 1
  55. }
  56.  
  57. # Get a list of remote shares
  58. $RemoteShares = (net view \\localhost) | % { if($_.IndexOf(' Disk ') -gt 0){ $_.Split('  ')[0] } }
  59. # If there are no shares, log and stop.
  60. if ($RemoteShares.Count -eq 0) {
  61.     scriptLog("Found no shares on the server.")
  62.     $Errors++
  63.     Exit 1
  64. }
  65. # Otherwise, we've found shares - Log and continue.
  66. scriptLog("Found " + ($RemoteShares.Count) + " SMB Shares; " + ($RemoteShares -join ','))
  67.  
  68. if (DoFullBackup) {
  69.     # Full backup routine
  70.     scriptLog("A full backup will be taken at this time")
  71.     if (!(Test-Path -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))))) {
  72.         New-Item -ItemType Directory -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd")))
  73.         New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt")
  74.         Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup Started: " + $ScriptStart)
  75.         Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value "Backup Type: Full"
  76.  
  77.         New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup.type")
  78.         Set-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup.type") -Value "Full"
  79.     }
  80.  
  81.     foreach ($Share in $RemoteShares) {
  82.         if (!(Test-Path -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+$Share))) {
  83.             New-Item -ItemType Directory -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+$Share)
  84.         }
  85.         scriptLog(("Backing up directory: "+$Share))
  86.         robocopy ($Source+"\"+$Share) ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+$Share) /E | Out-File ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+$Share+"-RoboCopy.log")
  87.         if ($LASTEXITCODE -eq 0 -or $LASTEXITCODE -eq 1) { Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup of shared folder completed. Folder name: " + $Share) }
  88.         else {
  89.             $Errors++
  90.             Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("There was an error during the robocopy of the shared folder. Examine the Robocopy log. Shared Folder: " + $Share + $LASTEXITCODE)
  91.             scriptLog(("There was an error during the robocopy of the shared folder. Examine the Robocopy log. Shared Folder: " + $Share + $LASTEXITCODE))
  92.         }
  93.     }
  94.     scriptLog("Full Backup has finished")
  95.     Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup Ended: " + (Get-Date))
  96.     Set-Content -Path $Destination"\Auto-Backup\Integ.bk" -Value (Get-Date)
  97. }
  98. else {
  99.     # Incremental routine
  100.     $FullBackupLocation = LastFullBackup
  101.    
  102.     # Stop the backup if a full backup cannot be found.
  103.     if ($FullBackupLocation -eq $null) {
  104.         scriptLog("A full backup could not be found.")
  105.         $Errors++
  106.         Exit 1
  107.     }
  108.  
  109.     # Create Backup Location
  110.     if (!(Test-Path -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))))) {
  111.         New-Item -ItemType Directory -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd")))
  112.         New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt")
  113.         Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup Started: " + $ScriptStart)
  114.         Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value "Backup Type: Incremental"
  115.  
  116.         New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup.type")
  117.         Set-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup.type") -Value "Incremental"
  118.     }
  119.  
  120.     scriptLog("An incremental backup will be taken at this time")
  121.     scriptLog(("Last Full Backup Location: " + $FullBackupLocation))
  122.  
  123.     foreach ($Share in $RemoteShares) {
  124.         foreach ($Item in Get-ChildItem ($Source+"\"+$Share) -Recurse) {
  125.             $FullItem = ($FullBackupLocation+"\"+($Item.FullName).Remove(0,($Source).Length))
  126.             if (!(Test-Path -Path $FullItem) -or $Item.LastWriteTime -gt (Get-Item -Path $FullItem).LastWriteTime -or $Item.Length -ne (Get-Item -Path $FullItem).Length) {
  127.                 try {
  128.                     New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+($Item.FullName).Remove(0,($Source).Length)) -Force
  129.                     Copy-Item -Path $Item.FullName -Destination ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+($Item.FullName).Remove(0,($Source).Length))
  130.                     scriptLog(("[Copied] " + $Item.FullName + " (" + ($Destination+"\Auto-Backup"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+($Item.FullName).Remove(0,($Source).Length)) + ")"))
  131.                 }
  132.                 catch {
  133.                     $Errors++
  134.                     scriptLog(("[Failed] " + $Item.FullName))
  135.                 }
  136.             }
  137.         }
  138.     }
  139.     scriptLog("Incremental Backup has finished")
  140.     Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup Ended: " + (Get-Date))
  141. }
  142.  
  143. # Retention Policy Routine
  144. foreach($Backup in Get-ChildItem -Path ($Destination+"\Auto-Backup\")) {
  145.     if ($Backup.GetType().ToString() -eq "System.IO.DirectoryInfo") {
  146.         try {
  147.             $CreateDate = ([datetime]::ParseExact($Backup.Name,"yyyyMMdd",$null))
  148.         }
  149.         catch {
  150.             $CreateDate = $Backup.CreationTime
  151.         }
  152.  
  153.         if ($CreateDate -lt $ScriptStart.AddDays(-$RetentionPolicy)) {
  154.             scriptLog("The backup for " + $CreateDate + " has expired due to the retention policy. This will be deleted.")
  155.             Remove-Item $Backup.FullName -Force -Recurse
  156.         }
  157.     }
  158. }
  159.  
  160. # Script Exit
  161. if ($Errors -eq 0) { scriptLog("Backup finished with no errors.") }
  162. if ($Errors -gt 0) { scriptLog("Errors were found while running the backup.") }
  163. Write-Host $Errors
  164. Exit $Errors
  165.  
  166. # Global Script for logging.
  167. function scriptLog([string]$LogMessage) {
  168.     if (!(Test-Path $Destination"\Auto-Backup\Auto-Backup.log")) { New-Item -ItemType File -Path $Destination"\Auto-Backup\Auto-Backup.log" }
  169.     $Today = Get-Date
  170.     Add-Content -Path $Destination"\Auto-Backup\Auto-Backup.log" -Value ([String]$Today+": "+$LogMessage)
  171.     Write-Host $Today": " $LogMessage
  172. }
  173.  
  174. # Should we run a full, or file change backup?
  175. function DoFullBackup {
  176.     if (!(Test-Path -Path $Destination"\Auto-Backup\Integ.bk")) {
  177.         New-Item -Path $Destination"\Auto-Backup\Integ.bk"
  178.         return $true
  179.     }
  180.     if ($Incremental -eq $false) { return $true }
  181.     $AllowedDate = (Get-Date).AddDays(-$RetentionPolicy)
  182.     $IntegContent = Get-Content -Path $Destination"\Auto-Backup\Integ.bk"
  183.     if (([datetime]$IntegContent) -lt $AllowedDate) {
  184.         return $true
  185.     }
  186.     return $false
  187. }
  188.  
  189. # Function to find last full backup
  190. function LastFullBackup {
  191.     $Latest = $null
  192.     $TimeCheck = (Get-Date).AddDays(-360)
  193.     foreach($Backup in Get-ChildItem -Path ($Destination+"\Auto-Backup\")) {
  194.         if ($Backup.GetType().ToString() -eq "System.IO.DirectoryInfo") {
  195.             if (Test-Path -Path ($Backup.FullName+"\Backup.type")) {
  196.                 if ((Get-Content -Path ($Backup.FullName+"\Backup.type")) -eq "Full") {
  197.                     if (([datetime]::ParseExact($Backup.Name,"yyyyMMdd",$null)) -gt $TimeCheck) {
  198.                         $TimeCheck = ([datetime]::ParseExact($Backup.Name,"yyyyMMdd",$null))
  199.                         $Latest = $Backup.FullName
  200.                     }
  201.                 }
  202.             }
  203.         }
  204.     }
  205.     return $Latest
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement