如何让Start-BitsTransfer递归复制?或为Copy-Item添加进度条?
关于Start-BitsTransfer递归复制与Copy-Item添加进度条的解决方案
问题背景
之前将备份恢复函数从Copy-Item改为Start-BitsTransfer,目的是利用其自带的进度条,但发现Start-BitsTransfer无法像原函数那样递归复制嵌套文件夹及其中的文件,完全不复制含文件的子文件夹。
示例文件夹结构:
c:\Users\username\AppData\Local\MyBackupFolder\Folder1\Subfolder1\user.config c:\Users\username\AppData\Local\MyBackupFolder\Folder2\file.xml c:\Users\username\AppData\Local\MyBackupFolder\Folder3\Subfolder2\severalFiles
原Copy-Item实现:
function Restore-From-Backup($Source, $Destination) { Copy-Item -Path $Source -Destination $Destination -Recurse }
修改后的Start-BitsTransfer实现:
function Restore-From-Backup($Source, $Destination) { Start-BitsTransfer -Source $Source -Destination $Destination -TransferType Download }
问题解答
1. 让Start-BitsTransfer实现递归复制
Start-BitsTransfer本身不支持直接递归复制文件夹,它的设计目标是针对单个或批量文件传输,而非文件夹层级的递归操作。但可以通过手动遍历源文件夹的所有文件,再批量传递给Start-BitsTransfer来实现递归效果,同时需要提前创建目标文件夹结构。
实现代码示例:
function Restore-From-Backup($Source, $Destination) { # 获取源文件夹下所有文件(递归) $files = Get-ChildItem -Path $Source -File -Recurse foreach ($file in $files) { # 计算目标文件路径,保持文件夹结构 $targetPath = $file.FullName.Replace($Source, $Destination) # 创建目标文件夹(如果不存在) $targetFolder = Split-Path -Path $targetPath -Parent if (-not (Test-Path -Path $targetFolder)) { New-Item -Path $targetFolder -ItemType Directory -Force | Out-Null } # 使用BITS传输单个文件 Start-BitsTransfer -Source $file.FullName -Destination $targetPath -TransferType Download } }
注:也可以将所有文件路径收集后一次性传递给
Start-BitsTransfer的-Source参数,减少任务创建开销,但需要确保目标路径与源文件一一对应。
2. 为Copy-Item添加进度条
如果不想用BITS的方式,可以给Copy-Item添加自定义进度条,通过遍历文件并结合Write-Progress实现:
实现代码示例:
function Restore-From-Backup($Source, $Destination) { # 获取源文件夹下所有文件(递归) $files = Get-ChildItem -Path $Source -File -Recurse $totalFiles = $files.Count $currentFile = 0 foreach ($file in $files) { $currentFile++ # 计算目标文件路径 $targetPath = $file.FullName.Replace($Source, $Destination) $targetFolder = Split-Path -Path $targetPath -Parent # 创建目标文件夹 if (-not (Test-Path -Path $targetFolder)) { New-Item -Path $targetFolder -ItemType Directory -Force | Out-Null } # 更新进度条 $progressParams = @{ Activity = "正在恢复备份" Status = "已处理 $currentFile/$totalFiles 个文件" PercentComplete = ($currentFile / $totalFiles) * 100 CurrentOperation = "复制文件:$($file.Name)" } Write-Progress @progressParams # 复制文件 Copy-Item -Path $file.FullName -Destination $targetPath -Force } # 完成后清除进度条 Write-Progress -Activity "正在恢复备份" -Completed }
这个函数会在复制过程中显示实时进度,包括已处理文件数、当前复制的文件名和进度百分比,效果接近BITS的进度条。
内容的提问来源于stack exchange,提问作者Blu3Rat
相关产品推荐
相关产品推荐

