我正在编写一个脚本,该脚本从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
感谢您的建议。
答案 0 :(得分:0)
您在这里有规范,但是您尚未显示代码,请征求意见。
也就是说,正如很多人所说的那样,这是不合时宜的,因为这里的目标是帮助无法运行的代码或类似的代码。那么,在这一点上,您是否尝试过您要问的问题,如果是,发生了什么事情?
所以,恕我直言……然而,既然您在这里。我们不要空手而归。
As per a similar ask here,接受的答案是...
…您在控制台上打开了当前的PSSession,然后您 正在尝试在后台作业中使用同一会话。这将 不起作用,因为您正在使用两个不同的PowerShell进程,并且 无法按原样在运行空间之间共享实时数据 反序列化并失去其所有功能。您将需要看 如果您的目标是共享,则可以创建自己的PowerShell运行空间 跨多个PowerShell会话的实时变量。
即使采用了上述方法,您仍然具有您提到的那些消耗限制,并且从技术上根据您的用例,您很可能最终还会遇到严重的性能问题。