Powershell foreach в партиях по 10 - PullRequest
       30

Powershell foreach в партиях по 10

0 голосов
/ 07 ноября 2019

У меня следующий код для получения данных из партнерского центра

$custIDs = Get-MicrosoftPartnerCustomers 
foreach ($custID in $custIDs)

{
 Export-MicrosoftOrganizationData -CustomerId $custID
 }

В этом цикле foreach у меня есть тысячи CustomerID, поэтому я хочу выполнить эту команду с шагом 10, в первой итерациизахватить первых 10 клиентов, в следующие 10 и т. д.

У меня есть код, который работает так, как я хочу, но гораздо медленнее, чем при циклическом обходе всех клиентов одновременно (и эта работа тоже медленная)

$custIDs = Get-MicrosoftPartnerCustomers 


$group = 10 # step of 10
$i = 0


do {
     $custIDs[$i..(($i+= $group) - 1)]
     '*****'

     Export-MicrosoftOrganizationData -CustomerId $custIDs

     }
      until ($i -ge $custIDs.count -1)




function Export-MicrosoftOrganizationData {
    [CmdletBinding()]
    param (
        # Customer ID from Microsoft Partner Center
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)][string[]]$CustomerId
    )

    begin {
        $ArrayOfOrganizations = [System.Collections.ArrayList]@()
    }

    process {
        $CustomerId.ForEach({
            $Organization = [Organization]::new()
            $Organization.PopulateMicrosoftData($_)
            $ArrayOfOrganizations.Add($Organization)
        })
    }

    end {
        $ArrayOfOrganizations.ForEach({Export-Csv -NoTypeInformation -Delimiter "," -Path .\TestOutputOrg.csv -InputObject $_ -Append})
    }
}

Есть ли более эффективный способ сделать это?

1 Ответ

1 голос
/ 07 ноября 2019

[$i..(($i+= $group) - 1)] неверно. Это устанавливает начальный $i слишком низким для каждого пакета, кроме первого, что означает, что вы выполняете слишком много работы, чем необходимо.

Вы имеете в виду [($i * $group)..(($i+1) * $group - 1)], то есть что-то вроде

$batches = for ($i = 0; $i -lt $custIDs.Count / $group; $i++) {
    ,$custIDs[($i * $group)..(($i+1) * $group - 1)]
}

Обратите внимание на , в начале, который гарантирует, что вы получите вложенный массив.


При этом я реструктурирую Export-MicrosoftOrganizationData. В первую очередь потому, что получение объектов и экспорт их представляют собой две разные вещи, и их не следует выполнять в одной и той же функции.

Это упрощает все - begin иБлоки end больше не нужны, нет необходимости в промежуточном массиве, и функция (назовем ее Get-MicrosoftOrganizationData) в целом становится более универсальной:

function Get-MicrosoftOrganizationData {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory, ValueFromPipeline)] # CustomerId from Microsoft Partner Center
        [string[]]$CustomerId
    )
    @($CustomerId) | ForEach-Object {
        $Organization = [Organization]::new()
        $Organization.PopulateMicrosoftData($_)
        $Organization
    }
}

Вызов Export-Csv не сложенв любом случае достаточно, чтобы быть заправленным в функцию:

$custIDs = Get-MicrosoftPartnerCustomers
$orgData = $custIDs | Get-MicrosoftOrganizationData
$orgData | Export-Csv -NoTypeInformation -Delimiter "," -Path .\TestOutputOrg.csv

По сути, вы могли бы даже поместить все это в одну строку.

В целом создание пакетов X из ввода может быть полезно длятестирование, но если вы все равно собираетесь обрабатывать все идентификаторов, это бесполезная стратегия.

...