繁体   English   中英

Powershell将BITS一次传输限制为4

[英]Powershell limiting BITS transfers to 4 at a time

我正在使用BITS将Office 365 ProPlus二进制文件传输到12个单独的文件共享的脚本。 我还想在屏幕上显示这些传输的进度。 我的问题是,我想一次将同时进行的BITS传输限制为不超过4次。 当一个作业完成时,我想开始队列中的下一个作业,并继续接收进度,直到所有作业完成。

到目前为止,这就是我所拥有的。 我首先从此功能开始,以处于挂起状态的所有网络位置创建我的所有BITS作业。

function Start-BinaryTransfer
{
[CmdletBinding()]
param
(
    [array]$DistrictsToUpdate
)

$Source = "$BaseSource\$UpdateChannel"

if ("All" -in $DistrictsToUpdate.Split(','))
{
    foreach ($Destination in $ReposList)
    {
        Copy-Item -Path $Source -Destination $($Destination.Location + '\') -Filter { $_.PSisContainer } -Recurse -ErrorAction SilentlyContinue
        Get-ChildItem -Path $Source -Recurse | Where-Object{ $_.PSisContainer } | ForEach-Object {
            $spath = $_.FullName.Remove(0, $Source.Length + 1)
            $BITSJobs += Start-BitsTransfer -Source $Source\$spath\*.* `
                                            -Destination "$($Destination.Location)\$UpdateChannel\$spath" `
                                            -DisplayName "$($Destination.District) File Transfer" `
                                            -Description "Transferring from [$Source] to [$($Destination.Location)\$UpdateChannel]" `
                                            -Suspended
        }
    }
}

创建完所有作业后,我然后尝试使用此While循环一次启动4个作业,并随即显示进度。 不幸的是,实际的行为是它将尝试立即启动所有12个作业,然后使网络资源中断。

While (Get-BitsTransfer | Where JobState -EQ "Suspended")
{
Get-BitsTransfer | Where JobState -EQ "Suspended" | ForEach-Object {
    for ($JobsCount = 0; $JobsCount -le 4; $JobsCount++)
    {
        if ($JobsCount -lt 4)
        {
            Resume-BitsTransfer -BitsJob $_ -Asynchronous
            Get-BitsTransfer | Where JobState -EQ "Transferring" | ForEach-Object {
                Write-Progress `
                               -Id $([math]::Abs($_.DisplayName.GetHashCode())) `
                               -Activity "$($_.DisplayName)" `
                               -Status "$($_.Description)" `
                               -CurrentOperation "$([math]::Floor($_.BytesTransferred / $_.BytesTotal * 100)) % Complete" `
                               -PercentComplete $([math]::Floor($_.BytesTransferred / $_.BytesTotal * 100))
            }
        }
      }
    }

    if (Get-BitsTransfer | Where JobState -EQ "Transferred")
    {
        Get-BitsTransfer | Where JobState -EQ "Transferred" | Complete- BitsTransfer
        $JobsCount--
    }
}

使用for -loop,您将每次运行将$JobsCount重置为0

for ($JobsCount = 0; $JobsCount -le 4; $JobsCount++)

像这样的事情应该起作用(只需对当前代码进行最少的更改):

$JobsCount = 0
While (Get-BitsTransfer | Where JobState -EQ "Suspended")
{
Get-BitsTransfer | Where JobState -EQ "Suspended" | ForEach-Object {
    # remove for-loop
        if ($JobsCount -lt 4)
        {
            $JobsCount++
            ...

您还必须修改while -loop,当前,当不再有JobState "Suspended"作业时,它将退出,但是您仍然必须等待JobState "Transferring"作业,并在它们为"Transferred"时完成。 建议: While ((Get-BitsTransfer) -ne $null)或更简单的While (Get-BitsTransfer)

感谢您的建议,达到了目的。 我计划进一步完善代码,但是到目前为止,这是我目前可以使用的。

function Update-JobProgress
{
    [CmdletBinding()]
    param ()

    Get-BitsTransfer | Where-Object { ($_.JobState -EQ "Transferring") -and ($_.DisplayName -Like "*File Transfer") } | ForEach-Object {
        Write-Progress -Id $([math]::Abs($_.DisplayName.GetHashCode())) `
                       -Activity "$($_.DisplayName)" `
                       -Status "$($_.Description)" `
                       -CurrentOperation "$([math]::Floor($_.BytesTransferred / $_.BytesTotal * 100)) % Complete" `
                       #-PercentComplete $([math]::Floor($_.BytesTransferred / $_.BytesTotal * 100))
    }
}


While (Get-BitsTransfer)
{
    $JobsCount = (Get-BitsTransfer | Where-Object { ($_.JobState -ne "Suspended") -and ($_.DisplayName -Like "*File Transfer") }).Count

    Get-BitsTransfer | Where-Object JobState -EQ "Suspended" | ForEach-Object {
        if ($JobsCount -lt 4)
        {
            Resume-BitsTransfer -BitsJob $_ -Asynchronous
            $JobsCount++
        }
    }

    Update-JobProgress

    if (Get-BitsTransfer | Where-Object { ($_.JobState -EQ "Transferred") -and ($_.DisplayName -Like "*File Transfer") })
    {
        Get-BitsTransfer | Where-Object { ($_.JobState -EQ "Transferred") -and ($_.DisplayName -Like "*File Transfer") } | ForEach-Object {
            Write-Progress `
                           -Id $([math]::Abs($_.DisplayName.GetHashCode())) `
                           -Activity "$($_.DisplayName)" `
                           -Completed
            $_ | Complete-BitsTransfer
            $JobsCount--
        }
    }
}

在测试中,我发现使用-PercentComplete开关在控制台窗口中实际显示滚动进度条时,结果不一致。 完成的第一份工作往往会流连忘返,并引起奇怪的视觉故障。 省略开关并放弃进度条似乎可以解决此问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM