通过 Powershell 检索 Office365 数据的更有效方法

通过 Powershell 检索 Office365 数据的更有效方法

我正在尝试从 Office 365 获取邮箱统计信息。这是当前脚本:

# Get credentials
$O365Creds = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList "[email protected]",$SecurePassword

# Create session
$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionURI https://ps.outlook.com/powershell -Credential $O365Creds -Authentication Basic -AllowRedirection
Import-PSSession $O365Session -AllowClobber

# Create report
Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | FT @{n="UserID";e={(Get-Mailbox $_.LegacyDN).Name}},LastLogonTime | Out-File -FilePath o365_logons.csv -Encoding utf8 -append

查看内存使用情况,似乎Get-Mailbox -ResultSize Unlimited在将其加载到内存中之前,内存使用量超过 1GB。大多数情况下它只是超时。这非常低效,因为我只对两列感兴趣。

有人对如何更有效地完成这项任务有什么建议吗?

答案1

根据 TheCleaner 和 MichelZ 的建议,我修改了脚本,按照字母范围对查询进行分页:

# Create credentials
$O365Creds = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList "[email protected]",$SecurePassword

# Create session
$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $O365Creds -Authentication Basic -AllowRedirection
Import-PSSession $O365Session -AllowClobber

# Initiate file
$CSVExport = "o365_logons.csv"
If (Test-Path $CSVExport){
    Remove-Item $CSVExport
}
"UserID,LastLogonTime" | Out-File -FilePath $CSVExport

# Loop through alphabet
foreach ($letter1 in [char]'a'..[char]'z') {
    foreach ($letter2 in [char]'a'..[char]'z') {
        $AccountNames = Get-Mailbox -Filter "{SamAccountName -like '$([char]$letter1)$([char]$letter2)*'}" -ResultSize Unlimited | Select -Expand Name

        # Skip if no accounts
        if (!$AccountNames) {
            Continue
        }

        foreach ($account in $AccountNames) {

            ## Some last logon could be null, using ForEach as workaround
            $last_logon = Get-MailboxStatistics -Identity $account | ForEach { $_.LastLogonTime }

            ## Print to CSV file
            $account,$last_logon -Join ','| Out-File -Append -FilePath $CSVExport
        }
    }
}

将在夜间进行试运行。

如果有人对如何使其更高效或更优雅有任何建议,请发表评论。

答案2

我会这样做:

# Get credentials
$O365Creds = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList "[email protected]",$SecurePassword

# Create session
$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionURI https://ps.outlook.com/powershell -Credential $O365Creds -Authentication Basic -AllowRedirection
Import-PSSession $O365Session -AllowClobber

# Create report

$Mailboxes = Get-Mailbox -Resultsize Unlimited

foreach ($mailbox in $Mailboxes) {
    $mailboxstats = Get-MailboxStatistics
    $mailboxstats | Add-Member -MemberType NoteProperty UserID -Value $mailbox.Name
    $mailboxstats | Export-CSV o365_logons.csv -NoTypeInformation -Append
    }

原始代码获取对象流,并同时将每个对象从对象中剥离出来,获取一个或两个属性,为一个属性引入另一个对象,将所有这些组合成一个对象,然后立即将其发送到 format-table,后者将其从对象中剥离出来。然后使用 out-file 发送到 CSV。

相反,此代码将邮箱对象数组放入一个数组中。然后循环遍历它们,为每个对象提取 Mailboxstats 对象,将邮箱的属性 (UserID) 添加到统计对象,然后使用 Export-CSV 将整个内容转储到 CSV 中。

即使您不使用整个邮箱统计对象,您至少也应该使用 Foreach-Object 循环,使用所需数据构建自定义对象,然后使用 Export-CSV 导出到 CSV。

这里使用的 foreach 循环每次向脚本块发送一个对象,从而减少管道中的数据量。

构建自定义对象来从多个来源(包括其他对象)收集所需的数据是一个强大的工具。

Export-CSV 是导出 csv 的正确工具。Out-File 看起来笨重且充满危险。

相关内容