在Start-Job中将活动的Powershell PSSession连接作为参数传递

时间:2019-03-27 16:09:07

标签: powershell office365

我正在编写一个脚本,该脚本从Exchange Online收集有关组织中每个邮箱的邮箱权限的数据。为此,我将所有邮箱数据收集到一个变量中,然后使用foreach遍历每个邮箱并检查应用于它的邮箱权限。当您使用超过15000个邮箱时,这会花费一些时间。

我想使用Powershell作业通过让多个作业检查权限并将它们附加到单个CSV文件来加快此过程。有没有一种方法可以将活动的PSSession传递到新作业中,以便该作业“共享”产生该作业的父进程的活动会话,并且不需要建立新的会话?

我可以在函数中进行New-PSSession调用,但是Microsoft在Exchange Online PSSessions中具有活动的会话限制,因此它将我一次可以运行的作业数量限制为3。其余的必须通过排队一会儿循环。如果我可以在多个作业之间共享一个会话,那么我将受到计算机资源的限制,而不是连接限制。

是否有人成功地将活动的PSSession传递给工作?

编辑:

我一直在使用运行空间来尝试通过Boe Prox的PoshRSJobs模块完成此任务。仍然很难使其正常工作。仅当我尝试在foreach语句中整理权限时,才创建或添加CSV。脚本块中的Write-Output也仅输出隐式远程信息,这也是奇怪的。

代码在下面。

Connect-ToOffice365TenantPSSession

$mailboxes = Get-Mailbox -ResultSize 10 -IncludeInactiveMailbox

$indexCount = 1

foreach ($mailbox in $mailboxes) {
$script = @"
`$cred = Import-Clixml -Path 'C:\Users\Foo\.credentials\StoredLocalCreds.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:\Scripts\MailboxPermissions.csv') {
        `$permissionObject | Export-Csv 'C:\Scripts\MailboxPermissions.csv' -NoTypeInformation -Append
    } else {
        New-Item -Path 'C:\Scripts\MailboxPermissions.csv'
        `$permissionObject | Export-Csv 'C:\Scripts\MailboxPermissions.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 个答案:

答案 0 :(得分:0)

您在这里有规范,但是您尚未显示代码,请征求意见。

也就是说,正如很多人所说的那样,这是不合时宜的,因为这里的目标是帮助无法运行的代码或类似的代码。那么,在这一点上,您是否尝试过您要问的问题,如果是,发生了什么事情?

所以,恕我直言……然而,既然您在这里。我们不要空手而归。

As per a similar ask here,接受的答案是...

  

…您在控制台上打开了当前的PSSession,然后您   正在尝试在后台作业中使用同一会话。这将   不起作用,因为您正在使用两个不同的PowerShell进程,并且   无法按原样在运行空间之间共享实时数据   反序列化并失去其所有功能。您将需要看   如果您的目标是共享,则可以创建自己的PowerShell运行空间   跨多个PowerShell会话的实时变量。

即使采用了上述方法,您仍然具有您提到的那些消耗限制,并且从技术上根据您的用例,您很可能最终还会遇到严重的性能问题。