Public/NC.Statistics.ps1
|
#Requires -Version 5.0 using namespace System.Management.Automation # Nebula.Core: Statistics =========================================================================================================================== function Export-MboxStatistics { <# .SYNOPSIS Exports mailbox (and archive) size/quota statistics. .DESCRIPTION Ensures an Exchange Online session, retrieves either all mailboxes or a single identity, calculates usage/quota information (optionally rounding quotas), and writes to CSV or returns objects to the pipeline. .PARAMETER UserPrincipalName Optional single mailbox identity. When omitted, exports all mailboxes to CSV. .PARAMETER CsvFolder Destination folder for the CSV file (defaults to current directory when exporting all mailboxes). .PARAMETER Round Round quota values up to the nearest integer GB. .PARAMETER BatchSize Number of processed mailboxes before flushing partial CSV output (defaults to 25). #> [CmdletBinding()] param( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('User', 'Identity')] [string]$UserPrincipalName, [string]$CsvFolder, [switch]$Round, [ValidateRange(1, 500)] [int]$BatchSize = 25 ) Set-ProgressAndInfoPreferences try { if (-not (Test-EOLConnection)) { Write-NCMessage "`nCan't connect or use Microsoft Exchange Online Management module. `nPlease check logs." -Level ERROR return } $exportAll = [string]::IsNullOrWhiteSpace($UserPrincipalName) $mailboxes = @() try { if ($exportAll) { $mailboxes = Get-Mailbox -ResultSize Unlimited -WarningAction SilentlyContinue } else { $mailboxes = @(Get-Mailbox -Identity $UserPrincipalName -ErrorAction Stop) } } catch { Write-NCMessage "Failed to retrieve mailbox information: $($_.Exception.Message)" -Level ERROR return } if (-not $mailboxes -or $mailboxes.Count -eq 0) { Write-NCMessage "No mailboxes found matching the provided criteria." -Level WARNING return } $folder = if ($CsvFolder) { Test-Folder $CsvFolder } else { Test-Folder $null } $statsBuffer = New-Object System.Collections.Generic.List[object] $processedCount = 0 $totalMailboxes = $mailboxes.Count $writeToCsv = $exportAll $csvPath = $null $csvInitialized = $false if ($writeToCsv) { $csvPath = New-File("$($folder)\$((Get-Date -Format $NCVars.DateTimeString_CSV))_M365-MailboxStatistics.csv") Write-NCMessage "Saving report to $csvPath" -Level DEBUG } foreach ($mailbox in $mailboxes) { $processedCount++ $percentComplete = (($processedCount / $totalMailboxes) * 100) Write-Progress -Activity "Processing $($mailbox.DisplayName)" -Status "$processedCount of $totalMailboxes ($($percentComplete.ToString('0.00'))%)" -PercentComplete $percentComplete $stats = Get-MailboxStatisticsSafe -Identity $mailbox.UserPrincipalName $mailboxSizeGb = if ($stats) { Convert-MbxSizeToGB -SizeObject $stats.TotalItemSize } else { "Error" } $archiveSize = $null if ($mailbox.ArchiveDatabase) { $archiveStats = Get-MailboxStatisticsSafe -Identity $mailbox.UserPrincipalName -Archive $archiveSize = if ($archiveStats) { Convert-MbxSizeToGB -SizeObject $archiveStats.TotalItemSize } else { "Error" } } $record = [pscustomobject][ordered]@{ UserName = $mailbox.DisplayName ServerName = $mailbox.ServerName Database = $mailbox.Database RecipientTypeDetails = $mailbox.RecipientTypeDetails PrimarySmtpAddress = $mailbox.PrimarySmtpAddress "Mailbox Size (GB)" = $mailboxSizeGb "Issue Warning Quota (GB)" = Resolve-MbxQuotaValue -RawValue $mailbox.IssueWarningQuota -Round:$Round "Prohibit Send Quota (GB)" = Resolve-MbxQuotaValue -RawValue $mailbox.ProhibitSendQuota -Round:$Round "Archive Database" = if ($mailbox.ArchiveDatabase) { $mailbox.ArchiveDatabase } else { $null } "Archive Name" = if ($mailbox.ArchiveDatabase) { $mailbox.ArchiveName } else { $null } "Archive State" = if ($mailbox.ArchiveDatabase) { $mailbox.ArchiveState } else { $null } "Archive Mailbox Size (GB)" = $archiveSize "Archive Warning Quota (GB)" = if ($mailbox.ArchiveDatabase) { Resolve-MbxQuotaValue -RawValue $mailbox.ArchiveWarningQuota -Round:$Round } else { $null } "Archive Quota (GB)" = if ($mailbox.ArchiveDatabase) { Resolve-MbxQuotaValue -RawValue $mailbox.ArchiveQuota -Round:$Round } else { $null } AutoExpandingArchiveEnabled = $mailbox.AutoExpandingArchiveEnabled } $statsBuffer.Add($record) | Out-Null if ($writeToCsv -and (($processedCount % $BatchSize) -eq 0)) { if ($csvInitialized) { $statsBuffer | Export-CSV -LiteralPath $csvPath -NoTypeInformation -Encoding $NCVars.CSV_Encoding -Delimiter $($NCVars.CSV_DefaultLimiter) -Append } else { $statsBuffer | Export-CSV -LiteralPath $csvPath -NoTypeInformation -Encoding $NCVars.CSV_Encoding -Delimiter $($NCVars.CSV_DefaultLimiter) $csvInitialized = $true } Write-NCMessage "Processed $processedCount / $totalMailboxes mailboxes, flushed batch to CSV." -Level VERBOSE $statsBuffer.Clear() } } if ($writeToCsv) { if ($statsBuffer.Count -gt 0) { if ($csvInitialized) { $statsBuffer | Export-CSV -LiteralPath $csvPath -NoTypeInformation -Encoding $NCVars.CSV_Encoding -Delimiter $($NCVars.CSV_DefaultLimiter) -Append } else { $statsBuffer | Export-CSV -LiteralPath $csvPath -NoTypeInformation -Encoding $NCVars.CSV_Encoding -Delimiter $($NCVars.CSV_DefaultLimiter) } } Write-NCMessage "Mailbox statistics exported to $csvPath." -Level SUCCESS } else { $statsBuffer } Write-Progress -Activity "Export complete" -Completed } finally { Restore-ProgressAndInfoPreferences } } |