123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- # Custom backup script
- function backup_aragorn {
- param(
- [switch]$diskoverride,
- [switch]$skipappdir,
- [string]$usedisk=$null)
-
-
- . (Join-Path $PSScriptRoot handle_exclude_lists.ps1)
- $myName = $env:COMPUTERNAME
- # Identify the backup disk
- if ($usedisk) {
- ($backupDisk, $partial) = get_specific_disk $usedisk
- } else {
- ($backupDisk, $partial) = check_disk $diskoverride
- }
- # Backup folder
- $backup_dir = "$HOME\Local"
- if (!(Test-Path $backup_dir) ) { mkdir $backup_dir }
- # Setup to use 7zip
- if (! (Test-Path 'C:\Program Files\7-Zip\7z.exe')) {
- Write-Error "Unable to locate 7-zip program file"
- throw 'Unable to locate 7-zip executable'
- }
- Set-Alias sz 'C:\Program Files\7-Zip\7z.exe'
-
- # Start the log file
- $logger = customLogger $backupDisk $myName
- $logger.StartLog()
-
- # Create a compressed version of the App Dir
- if (!($skipappdir)) {
- # Create the main backup file
- $backup_file = "$backup_dir\appdir.7z"
- # Make sure we start in the home folder
- Set-Location $HOME
- # Remove the previous file (start clean each time)
- if (Test-Path $backup_file) { Remove-Item $backup_file }
- # Load the exclude list
- $exclude = parse_appdata_exclude
- # Generate the compressed backup
- Invoke-Command -ScriptBlock { sz a -bb0 -t7z $args[0] $args[1] "$HOME\AppData"
- } -ArgumentList @($exclude, $backup_file)
- }
- ##
- ## Copy Everything to the disk
- ##
- # Define Options
- $basicOptions = "/MIR /COPY:DT /SL /XJ /DST /NDL /NP /TEE /R:1 /W:2 /LOG+:{0} /XF Thumbs.db" -f ($logger.logfile)
- $homeOptions = getRobocopyOptions $logger.logfile
-
- # Exclude Videos on smaller disks
- if ($partial) {
- $basicOptions += " /XD D:\david\Videos"
- }
- # Backup Home Directory
- backupDir $backupDisk $myName $HOME "David" $homeOptions
- # Backup the Data disk
- backupDir $backupDisk $myName "D:\David\" "dDavid" $basicOptions
- backupDir $backupDisk $myName "D:\DavidHome\" "dHome" $basicOptions
- backupDir $backupDisk $myName "D:\Public\" "dPublic" $basicOptions
- # Wrap up and update the log
- $logger.EndLog()
- }
- # Get the age of the backup to make sure we are using the right disk
- function check_disk($diskoverride=$false) {
- $backupDisk = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.VolumeName -match "Backup" -or $_.VolumeName -match "Seagate"}
- $partialBackup = $false
- # Test the age of the backup on the disk
- $last_updated = Get-Date (Get-Content (Join-Path $backupDisk.DeviceID "Aragorn\updated.txt"))
- if ($last_updated.AddDays(20) -gt (Get-Date)) {
- if (!($diskoverride)) {
- Write-Host -ForegroundColor DarkRed "This disk was last used less than 3 weeks ago. Override with -diskoverride."
- throw 'Unable to proceed'
- Exit 1
- }
- }
-
- # How much free space is there?
- if ($backupDisk.FreeSpace / 1gb -lt 100) {
- Write-Host -ForegroundColor DarkRed "There is less than 200gb free on the disk."
- throw 'Unable to proceed'
- Exit 1
- }
- # If it is a big disk, backup the videos as well
- if ($backupDisk.Size / 1gb -lt 1200) {
- Write-Host "Disk is small enough to do a partial backup"
- $partialBackup = $true
- }
- # Return the disk letter and whether to do the full backup
- return ($backupDisk.DeviceID, $partialBackup)
- }
- function get_specific_disk($letter) {
- $backupDisk = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -imatch $letter}
-
- # Return the disk letter and whether to do the full backup
- return ($backupDisk.DeviceID, $false)
- }
- function customLogger($backupDisk, $myName) {
- $logger = [PSCustomObject]@{
- startTime = Get-Date
- logfile = "$HOME\backuplog_{0}.txt" -f (Get-Date -UFormat %Y%m%d-%H%M)
- endTime = $null
- updateFile = ("{0}\{1}\updated.txt" -f ($backupDisk, $myName))
- }
-
- $StartLogScript = {
- Set-Content $this.logfile ( "`nStart Time: {0}`n`n" -f ($this.startTime) )
- }
- $memberParam = @{
- MemberType = "ScriptMethod"
- InputObject = $logger
- Name = "StartLog"
- Value = $StartLogScript
- }
- Add-Member @memberParam
- $EndLogScript = {
- Set-Content -Value (Get-Date) -Path $this.updateFile
-
- $this.endTime = Get-Date
- $start = "Start Time: {0}" -f $this.startTime
- $end = "Finish Time: {0}" -f $this.endTime
- Add-Content $this.logfile "`n`n$start`n$end"
- $ts = New-TimeSpan $this.startTime $this.endTime
- Write-Host ("The backup took {0:N1} minutes to complete" -f $ts.TotalMinutes)
- notepad $this.logfile
- }
- $memberParam = @{
- MemberType = "ScriptMethod"
- InputObject = $logger
- Name = "EndLog"
- Value = $EndLogScript
- }
- Add-Member @memberParam
-
- return $logger
- }
- # Backup the specified directory
- function backupDir($diskID, $myName, $src, $dstDir, $options, $basedir="")
- {
- $dst = "{0}\{1}\{2}" -f ($diskID, $myName, $dstDir)
-
- # If we are working with a special base directory, set it here
- if ($basedir) {
- $dst = "{0}\{1}\{2}" -f ($diskID, $basedir, $dstDir)
- }
- # Make sure it exists and start the backup
- if (!(Test-Path $dst)) { mkdir $dst }
- & robocopy $src $dst $options.Split()
- }
- # Robocopy options
- function getRobocopyOptions($log)
- {
- $excludeList = @"
- AppData
- Application Data
- MicrosoftEdgeBackups
- Cookies
- .cache
- .vscode
- "@
- # Build the exclude rules
- $xd = "/XD"
- foreach ($line in $excludeList.Split("`n")) {
- $xd += ' "' + "$HOME\" + $line.Trim() + '"'
- }
- # Return the exclude options
- return "/MIR /COPY:DT /SL /XJ /DST /NDL /NP /TEE /R:0 /W:2 /LOG+:$log /XF NTUSER.* UsrClass.* Thumbs.db $xd"
- }
- Export-ModuleMember backup_aragorn
|