PowerShell迁移7年以上文件:排除目录与权限问题调试求助
PowerShell 文件移动脚本问题修复
原脚本的核心问题
- 指定目录排除失效:
Get-ChildItem的-Exclude参数仅支持文件名/目录名的通配符匹配,无法直接排除完整路径的目录,导致你设置的$excludedFolder不起作用。 - 权限错误直接终止脚本:
Get-ChildItem默认遇到无权限访问的目录会抛出终止错误,直接停掉整个脚本,且未记录这类权限问题。 - 操作与需求不符:你需要移动文件,但原脚本用的是
Copy-Item(复制),不符合需求。
修复后的完整脚本
# 设置源目录和目标归档目录 $sourceDir = "T:\New T Drive" $destDir = "T:\New T Drive\Archive" # 计算7年前的时间阈值 $dateThreshold = (Get-Date).AddYears(-7) # 需要排除的无权限目录 $excludedFolder = "T:\New T Drive\Executive Director\" # 日志文件路径 $logFile = "C:\logs\file-migration.log" # 先确保日志目录存在,避免写入失败 $logDir = Split-Path -Path $logFile -Parent if (-not (Test-Path -Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null } # 获取所有符合条件的文件,同时捕获权限错误 Get-ChildItem -Path $sourceDir -Recurse -File -ErrorAction SilentlyContinue -ErrorVariable dirErrors | # 过滤掉排除目录下的文件,以及未超过7年未访问的文件 Where-Object { $_.FullName -notlike "$($excludedFolder.TrimEnd('\'))\*" -and $_.LastAccessTime -lt $dateThreshold } | ForEach-Object { # 构建目标路径,替换源目录为归档目录 $destPath = $_.FullName.Replace($sourceDir, $destDir) # 创建目标目录(如果不存在) $null = New-Item -ItemType Directory -Path (Split-Path -Path $destPath -Parent) -Force try { # 移动文件到归档目录,-Force覆盖已存在的同名文件 Move-Item -Path $_.FullName -Destination $destPath -Force Write-Host "✅ 已移动: $($_.FullName) -> $destPath" # 记录成功日志 "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 成功移动: $($_.FullName) -> $destPath" | Out-File $logFile -Append } catch { # 记录移动失败的错误 $errorMsg = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 移动失败: $($_.FullName),错误: $_" Write-Host $errorMsg -ForegroundColor Red $errorMsg | Out-File $logFile -Append } } # 处理获取文件时遇到的权限错误(无权限访问的目录) foreach ($err in $dirErrors) { if ($err.CategoryInfo.Category -eq 'PermissionDenied') { $errorMsg = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 无权限访问目录: $($err.TargetObject)" Write-Host $errorMsg -ForegroundColor Red $errorMsg | Out-File $logFile -Append } }
关键修复说明
- 正确排除目录:用
Where-Object检查文件的完整路径,确保不在排除目录的子路径下。TrimEnd('\')是为了避免排除目录末尾的斜杠导致匹配异常。 - 捕获目录权限错误:
-ErrorAction SilentlyContinue让Get-ChildItem碰到权限问题时不终止脚本,-ErrorVariable dirErrors把这些错误存起来,最后统一记录到日志。 - 替换为移动操作:把
Copy-Item改成Move-Item,直接完成文件移动;如果需要先复制验证,可换回Copy-Item,并在成功后添加Remove-Item $_.FullName删除源文件。 - 增强日志可读性:给日志加上时间戳,同时在控制台输出不同颜色的提示,方便实时查看状态。
- 优化性能:添加
-File参数直接只获取文件,不用后续再过滤!$_.PSIsContainer,减少不必要的处理。
内容的提问来源于stack exchange,提问作者Junior Vasquez
相关产品推荐
相关产品推荐

