PowerShell游戏备份脚本中Remove-Item删非空文件夹仍弹出确认的问题
Let's tackle your core problem first, then go through some overall improvements to make this script more robust and readable.
Core Issue: Remove-Item Still Asking for Confirmation
The reason you're getting a confirmation prompt when deleting non-empty folders is that you're missing the -Recurse parameter on Remove-Item when dealing with directories. When you pipe Get-ChildItem -Recurse to Remove-Item, any folders in that list will trigger a confirmation unless you explicitly tell PowerShell to delete their contents with -Recurse.
Your original code:
$TempFiles = Get-ChildItem $vSaveBak[$iB] -Recurse $TempFiles | Foreach ($_) { Remove-Item $_.Fullname -Force -ErrorAction SilentlyContinue -Confirm:$false}
Fixed Delete Logic
Replace that block with either of these simpler, reliable versions:
Option 1: Delete all contents of the backup directory directly (cleanest approach):
Remove-Item -Path "$($vSaveBak[$iB])\*" -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue
Option 2: Pipe with proper parameters:
Get-ChildItem -Path $vSaveBak[$iB] -Recurse | Remove-Item -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue
The -Recurse on Remove-Item tells PowerShell to delete all child items without prompting, and -Force handles hidden/system files.
Full Script Optimization
Here's a cleaned-up version of your script with better readability, error handling, and PowerShell best practices:
# Configuration - Update these paths/values as needed $saveDir = Join-Path $Env:USERPROFILE 'Zomboid\Saves\Sandbox' $gameDir = 'D:\SteamLibrary\SteamApps\common\ProjectZomboid' $maxBackups = 5 # Initialize variables $backupDirs = @() $backupCounter = 0 # Clear console and set working directory Clear-Host Set-Location -Path $saveDir -ErrorAction Stop # Launch Project Zomboid and get process ID try { $gameProcess = Start-Process -FilePath (Join-Path $gameDir 'ProjectZomboid64.exe') ` -WorkingDirectory $gameDir ` -PassThru ` -ErrorAction Stop $gamePID = $gameProcess.Id Write-Host "Launched Project Zomboid with PID: $gamePID" } catch { Write-Host "Failed to launch Project Zomboid: $_" -ForegroundColor Red exit 1 } # Wait for game process to start (in case of slow launch) while (-not (Get-Process -Id $gamePID -ErrorAction SilentlyContinue)) { Write-Host "Waiting for game process to start..." Start-Sleep -Seconds 10 } # Monitor game process and run backups every 30 seconds Write-Host "Monitoring game process. Backups will run automatically every 30 seconds..." while (Get-Process -Id $gamePID -ErrorAction SilentlyContinue) { Write-Verbose "Game process is running. Checking for save to backup..." # Reset counter when we reach max backups (cycle over old backups) if ($backupCounter -eq $maxBackups) { $backupCounter = 0 } # Get the most recently modified save folder (non-backup) $latestSave = Get-ChildItem -Path $saveDir -Directory | Sort-Object LastWriteTime -Descending | Select-Object -First 1 if (-not $latestSave) { Write-Verbose "No save folders found in $saveDir" Start-Sleep -Seconds 30 continue } # Skip if the latest save is already a backup if ($latestSave.Name -match 'Backup') { Write-Verbose "Latest save is a backup, skipping..." Start-Sleep -Seconds 30 continue } # Define backup directory path $backupPath = Join-Path $saveDir "$($latestSave.Name)_Backup_$backupCounter" # Create backup directory if it doesn't exist if (-not (Test-Path -Path $backupPath -PathType Container)) { $newBackupDir = New-Item -Path $backupPath -ItemType Directory -ErrorAction Stop $backupDirs += $newBackupDir Write-Host "Created backup directory: $backupPath" } # Clear existing contents of the backup directory Remove-Item -Path "$backupPath\*" -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue # Run Robocopy to perform backup (mirror with timestamps) Write-Verbose "Starting backup of $($latestSave.Name) to $backupPath..." Robocopy $latestSave.FullName $backupPath /e /dcopy:T /NFL /NDL /NJH /NJS /nc /ns /np # Increment backup counter $backupCounter++ # Wait 30 seconds before next check Start-Sleep -Seconds 30 } Write-Host "Game process terminated. Backup script exiting." -ForegroundColor Green
Key Improvements:
- Better Variable Names:
$saveDirinstead of$vSaveDirmakes the script easier to read and maintain. - Path Safety: Uses
Join-Pathto avoid issues with missing/duplicate slashes in paths (no more manual string concatenation errors). - Error Handling: Added
try/catchfor launching the game, and-ErrorAction Stopto catch critical failures early instead of letting the script hang. - Readable Output: Uses
Write-Verbosefor debug messages (run the script with-Verboseto see these) andWrite-Hostfor important user feedback with color coding. - Simplified Logic: Removed redundant variable assignments and streamlined the backup check flow to make the script easier to follow.
- Process Safety: Added a check to ensure the game process actually starts before entering the monitoring loop, preventing invalid PID errors.
内容的提问来源于stack exchange,提问作者sleepingcity

