Я пытаюсь получить статистику почтового ящика из Office 365. Это текущий сценарий:
# Get credentials
$O365Creds = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList "reports@o365.example.com",$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
загружается в память перед тем, как ее выгружать; более 1 ГБ памяти. В большинстве случаев это просто время ожидания. Это ужасно неэффективно, поскольку меня интересуют только две колонки.
У кого-нибудь есть предложения о том, как более эффективно выполнить эту задачу?
Согласно TheCleaner и MichelZ, я изменил скрипт для разбивки запроса по диапазонам букв:
# Create credentials
$O365Creds = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList "reports@o365.example.com",$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
}
}
}
Сделаем пробный запуск в течение ночи.
Если у кого-то есть рекомендации, как сделать это более эффективным или элегантным, прокомментируйте.
Я бы сделал следующее:
# Get credentials
$O365Creds = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList "reports@o365.example.com",$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
}
Исходный код принимает поток объектов и для каждого из них одновременно отделяет его от объекта, берет одно или два свойства, извлекает другой объект для одного свойства, объединяет все это в объект, а затем немедленно отправляет его в формат. table, что лишает его возможности быть объектом. Затем использует исходящий файл для отправки в CSV.
Вместо этого этот код переводит массив объектов почтового ящика в массив. Затем, просматривая их, извлекается объект Mailboxstats для каждого из них, добавляется свойство из почтового ящика (UserID) к объекту статистики и выгружается все это в CSV с помощью Export-CSV.
Даже если вы не используете весь объект статистики почтового ящика, вам следует по крайней мере использовать цикл Foreach-Object, создать собственный объект с нужными данными, а затем экспортировать в CSV с помощью Export-CSV.
Используемый здесь цикл foreach отправляет в блок сценария один объект за раз, тем самым уменьшая объем данных в конвейере.
Создание настраиваемого объекта для сбора необходимых данных из нескольких источников, включая другие объекты, является мощным инструментом.
Export-CSV - правильный инструмент для экспорта CSV. Out-File кажется неуклюжим и чреватым опасностями.