PowerShell处理大用户的速度非常慢-有更好的方法吗?

PowerShell处理大用户的速度非常慢-有更好的方法吗?,powershell,office365,exchange-server,export-to-csv,Powershell,Office365,Exchange Server,Export To Csv,我一直在使用Office365许可证跟踪。实际上看起来不错,但完成这个过程需要太多时间。大部分时间都花在Get-MsolUser上,并行计算可能会有所改进(在处理用户1时,您已经在获取用户2的数据,等等…)顺便说一句,我们有大约3000多名云用户,我如何提高脚本的速度 $T1 = @() $O365Users = Get-MsolUser -All ForEach ($O365User in $O365Users) { $ADuser = Get-ADUser -Filter { Use

我一直在使用Office365许可证跟踪。实际上看起来不错,但完成这个过程需要太多时间。大部分时间都花在Get-MsolUser上,并行计算可能会有所改进(在处理用户1时,您已经在获取用户2的数据,等等…)顺便说一句,我们有大约3000多名云用户,我如何提高脚本的速度

$T1 = @()
$O365Users = Get-MsolUser -All
ForEach ($O365User in $O365Users)
{
    $ADuser = Get-ADUser -Filter { UserPrincipalName -eq $O365User.UserPrincipalName } -Properties whenCreated, Enabled, lastlogondate
    $O365Stats = Get-MailboxStatistics $O365User.DisplayName -ErrorAction SilentlyContinue
    $O365Smtp =  Get-Recipient $O365User.DisplayName -ErrorAction SilentlyContinue
    If ($O365Stats -and $O365Smtp) {
    If (($ADUser.Enabled -eq $true) -and ($O365User.isLicensed -eq $true))
    {
        $T1 += New-Object psobject -Property @{
            CollectDate = $(Get-Date);
            ADUserUPN = $($ADUser.UserPrincipalName);
            O365UserUPN = $($O365User.UserPrincipalName);
            ADUserCreated = $($ADUser.whenCreated);
            ADUserEnabled = $($ADUser.Enabled);
            ADLastLogonDate = $($ADUser.LastLogonDate);
            O365Licensed = $($O365User.isLicensed);
            O365LastLogonTime = $($O365Stats.LastLogonTime);
            O365SMTPAddress = $($O365Smtp.PrimarySMTPAddress)
        }
    }
}
}
$T1 = $T1 | Sort-Object -Property ADUserCreated
$T1 | Format-Table
$T1 | Export-Csv -Path $OutputFile -NoTypeInformation
Write-Host "Output to $OutputFile"

在Powershell中为您提供并行设置

我想让你看看PS的工作流程

我们有-parallel,这将帮助您进行并行通话

除此之外,我们还有一个函数用于调用并行

这是它的链接:


注意:示例在函数本身中提到。编译后,您也可以对该函数使用get help

使用管道、早期过滤和避免附加到阵列应该已经大大加快了速度:

Get-MsolUser -All | Where-Object {
    $_.IsLicensed
} | ForEach-Object {
    $upn = $_.UserPrincipalName
    Get-ADUser -Filter "UserPrincipalName -eq '$upn'" -Properties whenCreated, Enabled, lastlogondate
} | Where-Object {
    $_.Enabled
} | ForEach-Object {
    $O365Stats = Get-MailboxStatistics $_.DisplayName -ErrorAction SilentlyContinue
    $O365Smtp  = Get-Recipient $_.DisplayName -ErrorAction SilentlyContinue
    if ($O365Stats -and $O365Smtp) {
        New-Object -Type PSObject -Property @{
            'CollectDate'       = Get-Date
            'ADUserUPN'         = $_.UserPrincipalName
            'O365UserUPN'       = $_.UserPrincipalName
            'ADUserCreated'     = $_.whenCreated
            'ADUserEnabled'     = $_.Enabled
            'ADLastLogonDate'   = $_.LastLogonDate
            'O365Licensed'      = $true
            'O365LastLogonTime' = $O365Stats.LastLogonTime
            'O365SMTPAddress'   = $O365Smtp.PrimarySMTPAddress
        }
    }
} | Sort-Object -Property ADUserCreated | Export-Csv -Path $OutputFile -NoType

还有,为什么每个人都对子表达式如此着迷?在你需要的地方使用它们。当它们不必要时,不要用它们混淆你的代码。

就像你说的,并行它。谢谢你说的人,我怎样才能重建我的脚本?请澄清一下,谢谢你,我怎样才能把我的脚本和调用并行函数结合起来呢?我说得对吗?调用Parallel-scriptfile myscript.ps1-runspaceTimeout 10-throttle10@Arbelac:是的,那应该可以做你的工作。。。你说得对,我会尽快检查。我收到一个警告,比如:默认情况下,只返回前1000个项目。使用ResultSize参数指定返回的项目数。要返回所有项目,请指定“-ResultSize Unlimited”。请注意,根据项目的实际数量,返回所有项目可能需要很长时间并消耗大量内存。此外,我们不建议将结果存储在变量中。相反,将结果通过管道传输到另一个任务或脚本以执行批处理更改。你推荐什么?你从哪里得到的警告?AFAICS除了
Get-MsolUser
之外的所有cmdlet都应该返回单个项目,但是根据文档,
Get-MsolUser
的参数应该是
-MaxResults
(默认值为500),不是
-ResultSize
。从我看到的情况来看,我在脚本运行期间不断收到这些警告,我也不知道这些警告的确切来源。最后,如果我运行上述脚本(未编辑),则不会收到类似的警告。请尝试我的更新答案。你还在收到那个警告吗?如果删除
排序对象
步骤,它是否会保留?