backup_aragorn.psm1 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. # Custom backup script
  2. function backup_aragorn {
  3. param(
  4. [switch]$diskoverride,
  5. [switch]$skipappdir,
  6. [string]$usedisk=$null)
  7. . (Join-Path $PSScriptRoot handle_exclude_lists.ps1)
  8. $myName = $env:COMPUTERNAME
  9. # Identify the backup disk
  10. if ($usedisk) {
  11. ($backupDisk, $partial) = get_specific_disk $usedisk
  12. } else {
  13. ($backupDisk, $partial) = check_disk $diskoverride
  14. }
  15. # Backup folder
  16. $backup_dir = "$HOME\Local"
  17. if (!(Test-Path $backup_dir) ) { mkdir $backup_dir }
  18. # Setup to use 7zip
  19. if (! (Test-Path 'C:\Program Files\7-Zip\7z.exe')) {
  20. Write-Error "Unable to locate 7-zip program file"
  21. throw 'Unable to locate 7-zip executable'
  22. }
  23. Set-Alias sz 'C:\Program Files\7-Zip\7z.exe'
  24. # Start the log file
  25. $logger = customLogger $backupDisk $myName
  26. $logger.StartLog()
  27. # Create a compressed version of the App Dir
  28. if (!($skipappdir)) {
  29. # Create the main backup file
  30. $backup_file = "$backup_dir\appdir.7z"
  31. # Make sure we start in the home folder
  32. Set-Location $HOME
  33. # Remove the previous file (start clean each time)
  34. if (Test-Path $backup_file) { Remove-Item $backup_file }
  35. # Load the exclude list
  36. $exclude = parse_appdata_exclude
  37. # Generate the compressed backup
  38. Invoke-Command -ScriptBlock { sz a -bb0 -t7z $args[0] $args[1] "$HOME\AppData"
  39. } -ArgumentList @($exclude, $backup_file)
  40. }
  41. ##
  42. ## Copy Everything to the disk
  43. ##
  44. # Define Options
  45. $basicOptions = "/MIR /COPY:DT /SL /XJ /DST /NDL /NP /TEE /R:1 /W:2 /LOG+:{0} /XF Thumbs.db" -f ($logger.logfile)
  46. $homeOptions = getRobocopyOptions $logger.logfile
  47. # Exclude Videos on smaller disks
  48. if ($partial) {
  49. $basicOptions += " /XD D:\david\Videos"
  50. }
  51. # Backup Home Directory
  52. backupDir $backupDisk $myName $HOME "David" $homeOptions
  53. # Backup the Data disk
  54. backupDir $backupDisk $myName "D:\david\" "dDavid" $basicOptions
  55. backupDir $backupDisk $myName "D:\public\" "dPublic" $basicOptions
  56. # Wrap up and update the log
  57. $logger.EndLog()
  58. }
  59. # Get the age of the backup to make sure we are using the right disk
  60. function check_disk($diskoverride=$false) {
  61. $backupDisk = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.VolumeName -match "Backup" -or $_.VolumeName -match "Seagate"}
  62. $partialBackup = $false
  63. # Test the age of the backup on the disk
  64. $last_updated = Get-Date (Get-Content (Join-Path $backupDisk.DeviceID "Aragorn\updated.txt"))
  65. if ($last_updated.AddDays(20) -lt (Get-Date)) {
  66. if (!($diskoverride)) {
  67. Write-Host -ForegroundColor DarkRed "This disk was last used less than 3 weeks ago. Override with -diskoverride."
  68. #throw 'Unable to proceed'
  69. Exit 1
  70. }
  71. }
  72. # How much free space is there?
  73. if ($backupDisk.FreeSpace / 1gb -lt 20) {
  74. Write-Host -ForegroundColor DarkRed "There is less than 20gb free on the disk."
  75. #throw 'Unable to proceed'
  76. Exit 1
  77. }
  78. # If it is a big disk, backup the videos as well
  79. if ($backupDisk.Size / 1gb -lt 1200) {
  80. Write-Host "Disk is small enough to do a partial backup"
  81. $partialBackup = $true
  82. }
  83. # Return the disk letter and whether to do the full backup
  84. return ($backupDisk.DeviceID, $partialBackup)
  85. }
  86. function get_specific_disk($letter) {
  87. $backupDisk = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -imatch $letter}
  88. # Return the disk letter and whether to do the full backup
  89. return ($backupDisk.DeviceID, $false)
  90. }
  91. function customLogger($backupDisk, $myName) {
  92. $logger = [PSCustomObject]@{
  93. startTime = Get-Date
  94. logfile = "$HOME\backuplog_{0}.txt" -f (Get-Date -UFormat %Y%m%d-%H%M)
  95. endTime = $null
  96. updateFile = ("{0}\{1}\updated.txt" -f ($backupDisk, $myName))
  97. }
  98. $StartLogScript = {
  99. Set-Content $this.logfile ( "`nStart Time: {0}`n`n" -f ($this.startTime) )
  100. }
  101. $memberParam = @{
  102. MemberType = "ScriptMethod"
  103. InputObject = $logger
  104. Name = "StartLog"
  105. Value = $StartLogScript
  106. }
  107. Add-Member @memberParam
  108. $EndLogScript = {
  109. Set-Content -Value (Get-Date) -Path $this.updateFile
  110. $this.endTime = Get-Date
  111. $start = "Start Time: {0}" -f $this.startTime
  112. $end = "Finish Time: {0}" -f $this.endTime
  113. Add-Content $this.logfile "`n`n$start`n$end"
  114. $ts = New-TimeSpan $this.startTime $this.endTime
  115. Write-Host ("The backup took {0:N1} minutes to complete" -f $ts.TotalMinutes)
  116. notepad $this.logfile
  117. }
  118. $memberParam = @{
  119. MemberType = "ScriptMethod"
  120. InputObject = $logger
  121. Name = "EndLog"
  122. Value = $EndLogScript
  123. }
  124. Add-Member @memberParam
  125. return $logger
  126. }
  127. # Backup the specified directory
  128. function backupDir($diskID, $myName, $src, $dstDir, $options, $basedir="")
  129. {
  130. $dst = "{0}\{1}\{2}" -f ($diskID, $myName, $dstDir)
  131. # If we are working with a special base directory, set it here
  132. if ($basedir) {
  133. $dst = "{0}\{1}\{2}" -f ($diskID, $basedir, $dstDir)
  134. }
  135. # Make sure it exists and start the backup
  136. if (!(Test-Path $dst)) { mkdir $dst }
  137. & robocopy $src $dst $options.Split()
  138. }
  139. # Robocopy options
  140. function getRobocopyOptions($log)
  141. {
  142. $excludeList = @"
  143. AppData
  144. Application Data
  145. MicrosoftEdgeBackups
  146. Cookies
  147. .cache
  148. .vagrant.d
  149. "@
  150. # Build the exclude rules
  151. $xd = "/XD"
  152. foreach ($line in $excludeList.Split("`n")) {
  153. $xd += ' "' + "$HOME\" + $line.Trim() + '"'
  154. }
  155. # Return the exclude options
  156. return "/MIR /COPY:DT /SL /XJ /DST /NDL /NP /TEE /R:0 /W:2 /LOG+:$log /XF NTUSER.* UsrClass.* Thumbs.db $xd"
  157. }
  158. Export-ModuleMember backup_aragorn