phil revised this gist 1 week ago. Go to revision
1 file changed, 71 insertions
backup-configs.ps1(file created)
| @@ -0,0 +1,71 @@ | |||
| 1 | + | <# | |
| 2 | + | .SYNOPSIS | |
| 3 | + | Scans Program Files directories on a source drive for critical config/license files | |
| 4 | + | and mirrors them to a backup location using Robocopy, preserving directory structure. | |
| 5 | + | ||
| 6 | + | .DESCRIPTION | |
| 7 | + | 1. Scans "Program Files" and "Program Files (x86)" on the source drive. | |
| 8 | + | 2. Looks for specific extensions (.ini, .lic, .db, etc.). | |
| 9 | + | 3. Calculates the destination path by swapping the drive root. | |
| 10 | + | 4. Uses Robocopy to copy the file (and its attributes/timestamps). | |
| 11 | + | #> | |
| 12 | + | ||
| 13 | + | # --- CONFIGURATION --- | |
| 14 | + | $SourceDrive = "D:" | |
| 15 | + | $BackupRoot = "C:\shared\share\backups\rtp\lynch" | |
| 16 | + | ||
| 17 | + | # The folders to scan on the Source Drive | |
| 18 | + | $ScanPaths = @( | |
| 19 | + | "$SourceDrive\Program Files", | |
| 20 | + | "$SourceDrive\Program Files (x86)" | |
| 21 | + | ) | |
| 22 | + | ||
| 23 | + | # The extensions to look for | |
| 24 | + | $Extensions = @( | |
| 25 | + | "*.ini", "*.conf", "*.cfg", "*.lic", "*.key", | |
| 26 | + | "*.mdb", "*.db", "*.sqlite", "*.dat", "*.xml", | |
| 27 | + | "*.properties", "*.config" | |
| 28 | + | ) | |
| 29 | + | # --------------------- | |
| 30 | + | ||
| 31 | + | foreach ($scanPath in $ScanPaths) { | |
| 32 | + | if (Test-Path $scanPath) { | |
| 33 | + | Write-Host "Scanning $scanPath for critical files..." -ForegroundColor Cyan | |
| 34 | + | ||
| 35 | + | # Get all matching files | |
| 36 | + | $foundFiles = Get-ChildItem -Path $scanPath -Include $Extensions -Recurse -ErrorAction SilentlyContinue | |
| 37 | + | ||
| 38 | + | foreach ($file in $foundFiles) { | |
| 39 | + | # 1. Determine the relative path (e.g., \Program Files\App\config.ini) | |
| 40 | + | # We strip the "D:" part from the FullName | |
| 41 | + | $relativePath = $file.FullName.Substring($SourceDrive.Length) | |
| 42 | + | ||
| 43 | + | # 2. Build the destination file path | |
| 44 | + | # Result: C:\backup\lynch\Program Files\App\config.ini | |
| 45 | + | $destFileFull = Join-Path -Path $BackupRoot -ChildPath $relativePath | |
| 46 | + | ||
| 47 | + | # 3. Get the destination FOLDER (Robocopy needs the folder, not the file name) | |
| 48 | + | $destFolder = Split-Path -Path $destFileFull -Parent | |
| 49 | + | ||
| 50 | + | # 4. Get just the file name for Robocopy | |
| 51 | + | $fileName = $file.Name | |
| 52 | + | ||
| 53 | + | # 5. Run Robocopy | |
| 54 | + | # Source folder is the parent of the found file | |
| 55 | + | $srcFolder = $file.DirectoryName | |
| 56 | + | ||
| 57 | + | Write-Host "Backing up: $fileName" -ForegroundColor Gray | |
| 58 | + | ||
| 59 | + | # /COPY:DAT = Copy Data, Attributes, Timestamps | |
| 60 | + | # /R:0 /W:0 = No retries (fail fast if locked) | |
| 61 | + | # /NJH /NJS = No Job Header/Summary (keeps output clean) | |
| 62 | + | # /NFL /NDL = No File/Dir List (we already printed the name) | |
| 63 | + | # /XJ = Exclude Junction points | |
| 64 | + | robocopy "$srcFolder" "$destFolder" "$fileName" /COPY:DAT /R:0 /W:0 /NJH /NJS /NFL /NDL /XJ | |
| 65 | + | } | |
| 66 | + | } else { | |
| 67 | + | Write-Warning "Path not found: $scanPath" | |
| 68 | + | } | |
| 69 | + | } | |
| 70 | + | ||
| 71 | + | Write-Host "`nBackup Complete." -ForegroundColor Green | |
Newer
Older