You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:47:14