Передача активного соединения Powershell PSSession в качестве аргумента в Start-Job

#powershell #office365

#powershell #office365

Вопрос:

Я пишу скрипт, который собирает данные из Exchange Online, касающиеся разрешений почтовых ящиков для каждого почтового ящика в нашей организации. Для этого я собираю все данные почтового ящика в переменную, затем использую foreach для перебора каждого почтового ящика и проверки разрешений почтового ящика, примененных к нему. Это требует времени, когда вы работаете с более чем 15000 почтовыми ящиками.

Я хотел бы использовать задания Powershell, чтобы ускорить этот процесс, запустив несколько заданий, проверяющих разрешения и добавляющих их в один CSV-файл. Есть ли способ передать активную PSSession в новое задание, чтобы задание «совместно использовало» активный сеанс родительского процесса, который породил задание, и не требовало установки нового?

Я мог бы поместить вызов New-PSSession в функцию, но у Microsoft есть ограничения на активные сеансы в Exchange Online PSSessions, поэтому это ограничило бы количество заданий, которые я мог бы запускать одновременно, до 3. Остальные должны быть поставлены в очередь через цикл while. Если бы я мог совместно использовать один сеанс между несколькими заданиями, я был бы ограничен ресурсами компьютера, а не ограничениями на подключение.

Кто-нибудь ранее успешно передавал активную PSSession в задание?

Редактировать:

Я работал над использованием runspaces, чтобы попытаться выполнить это с помощью модуля PoshRSJobs от Boe Prox. Все еще возникают некоторые трудности с его правильной работой. Не создает CSV или не добавляет к нему, но только если я пытаюсь отсортировать разрешения в инструкции foreach. Write-Output Внутри scriptblock выводится только неявная информация об удаленном подключении, что тоже странно.

Код приведен ниже.

 Connect-ToOffice365TenantPSSession

$mailboxes = Get-Mailbox -ResultSize 10 -IncludeInactiveMailbox

$indexCount = 1

foreach ($mailbox in $mailboxes) {
$script = @"
`$cred = Import-Clixml -Path 'C:UsersFoo.credentialsStoredLocalCreds.xml'

`$o365Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential `$cred -Authentication Basic -AllowRedirection

Import-PSSession `$o365Session -CommandName @('Get-Mailbox','Get-MailboxPermission')

`$internal_mailbox = `$Using:mailbox
`$mailboxPermissions = `$internal_mailbox | Get-MailboxPermission

foreach (`$permission in (`$mailboxPermissions | Where-Object {`$_.User -match 'tenantName|companyDomain'}))
{
    `$userPermissions = `$permission | Select-Object Identity, User, AccessRights

    `$permissionObject = [PSCustomObject]@{
        "MailboxName" = `$userPermissions.Identity
        "MailboxAddress" = `$internal_mailbox.PrimarySmtpAddress
        "MailboxType" = `$internal_mailbox.RecipientTypeDetails
        "UserWithAccess" = `$userPermissions.User
        "AccessRights" = `$userPermissions.AccessRights
    }

    if (Test-Path 'C:ScriptsMailboxPermissions.csv') {
        `$permissionObject | Export-Csv 'C:ScriptsMailboxPermissions.csv' -NoTypeInformation -Append
    } else {
        New-Item -Path 'C:ScriptsMailboxPermissions.csv'
        `$permissionObject | Export-Csv 'C:ScriptsMailboxPermissions.csv' -NoTypeInformation -Append
    }

    Write-Output `$permissionObject
}
"@

    $scriptBlock = [scriptblock]::Create($script)

    $continue = $false

    do
    {
        if ((Get-RSJob | Where-Object {$_.State -eq "Running"}).count -lt 3) {
            Start-RSJob -Name "Mailbox $indexCount" -ScriptBlock $scriptBlock

            $indexCount  
            $continue = $true
        }
        else {
            Start-Sleep 1
        }
    } while ($continue -eq $false)
}

Get-RSJob | Receive-RSJob
  

Спасибо за предложения.

Ответ №1:

Здесь у вас есть спецификации, но вы не показываете код и все же спрашиваете мнение.

Это, как многие сказали бы здесь, не по теме, потому что цель здесь — помочь с кодом, который не работает или тому подобное. Итак, на данный момент вы пробовали то, о чем просите, и если да, то что произошло?

Итак, ИМХО … И все же, поскольку вы здесь. давайте не будем отправлять вас с пустыми руками.

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

… на вашей консоли открыта текущая PSSession, а затем вы пытаетесь использовать этот же сеанс в фоновом задании. Это не сработает, поскольку вы используете два разных процесса PowerShell и не можете совместно использовать текущие данные между областями выполнения, поскольку они десериализуются и теряют все свои возможности. Вам нужно будет рассмотреть возможность создания собственных рабочих пространств PowerShell, если ваша цель — совместно использовать переменные в режиме реального времени в нескольких сеансах PowerShell.

Даже с учетом вышеизложенного у вас все еще есть указанные вами ограничения потребления, и технически, исходя из вашего варианта использования, вы, скорее всего, также столкнетесь с серьезными проблемами с производительностью.

Комментарии:

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