Биты, ограничивающие Powershell, переносятся на 4 одновременно - PullRequest
0 голосов
/ 07 октября 2018

Я работаю над сценарием для переноса двоичных файлов Office 365 ProPlus в 12 отдельных файловых ресурсов с помощью BITS.Я хочу также отображать ход этих переводов на экране.Моя проблема в том, что я хочу ограничить количество одновременных переводов 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
        }
    }
}

После создания всех заданий я пытаюсь использовать этот цикл «В течение», чтобы запустить 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--
    }
}

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Спасибо за предложение, который сделал свое дело.Я планирую доработать свой код, но вот то, что у меня пока есть, что в настоящее время работает.

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 для фактического отображения прогресса прокрутки.решетки в окне консоли;первая работа, которая завершается, имеет тенденцию задерживаться и вызывает странные визуальные глюки.Отказ от переключения и отказ от индикаторов выполнения, похоже, решают проблему.

0 голосов
/ 07 октября 2018

С for -циклом вы сбрасываете $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)

...