PowerShell复杂备份恢复脚本求助:文件还原路径异常排查
Hey there! Let's work through optimizing your PowerShell backup/restore script to fix that frustrating drive-not-found error and clean up the logic.
First, let's break down the core issue you hit: when using pscustomobject to track file paths, passing the entire object directly to Copy-Item causes PowerShell to convert it to a string (like @{name=Device.txt; originpath=C:\...}), which the cmdlet misinterprets as a drive name. The temporary fix of assigning properties to variables works, but we can make the script cleaner and more robust.
Optimized Script: Backup + Restore with Structured Records
This version uses a structured approach to track file details, supports both in-memory storage (ArrayList) and persistent CSV storage, and avoids the path misinterpretation bug.
Step 1: Backup Phase (Track Files & Save Records)
# Define your list of files to backup (can also import this from a CSV if needed) $targetFiles = @( "C:\Example\Device.txt", "D:\Config\Settings.ini", "E:\Documents\CriticalFile.docx" ) # Set your backup directory (create it if it doesn't exist) $backupRoot = "C:\MySecureBackup" if (-not (Test-Path $backupRoot)) { New-Item -ItemType Directory -Path $backupRoot | Out-Null } # Initialize a collection to store backup records $backupLog = @() foreach ($file in $targetFiles) { # Skip if the source file doesn't exist if (-not (Test-Path $file -PathType Leaf)) { Write-Warning "Skipping missing file: $file" continue } # Get file details and build backup path $fileName = Split-Path $file -Leaf $backupPath = Join-Path $backupRoot $fileName # Perform the backup Copy-Item -Path $file -Destination $backupPath -Force # Create a structured record to track original + backup paths $record = [PSCustomObject]@{ OriginalFullPath = $file BackupFullPath = $backupPath FileName = $fileName } $backupLog += $record } # Optional: Save records to CSV for cross-session restore $backupLog | Export-Csv -Path "$backupRoot\BackupManifest.csv" -NoTypeInformation Write-Host "Backup completed. $($backupLog.Count) files backed up."
Step 2: Restore Phase (Use Records to Restore to Original Paths)
# Load backup records (use CSV if restoring in a new session, or $backupLog if same session) $backupLog = Import-Csv -Path "$backupRoot\BackupManifest.csv" foreach ($entry in $backupLog) { # Extract the actual path values (this fixes the drive-not-found error!) $originalPath = $entry.OriginalFullPath $backupSource = $entry.BackupFullPath # Verify backup file exists before restoring if (Test-Path $backupSource -PathType Leaf) { Copy-Item -Path $backupSource -Destination $originalPath -Force Write-Host "Successfully restored: $originalPath" } else { Write-Warning "Backup file missing, cannot restore: $backupSource" } }
Key Improvements Over Your Initial Script
- Clear Structured Tracking: The
pscustomobjectexplicitly storesOriginalFullPathandBackupFullPath, eliminating logic confusion from vague array structures. - Error Prevention: We validate file existence before backup/restore, so you get clear warnings instead of silent failures.
- No More Drive Errors: By explicitly extracting property values (
$entry.OriginalFullPathinstead of passing$entry), we avoid PowerShell converting the object to a garbage string path. - Flexible Storage: Choose between in-memory
$backupLog(for single-session operations) or CSV (for restoring days/weeks later without re-running the backup).
This approach stays true to your requirement of avoiding simple A→B→A copies, and keeps the script maintainable if you need to add more files or adjust logic later.
内容的提问来源于stack exchange,提问作者Kevin

