Exchange-Online/Get-MailboxSummary.ps1
|
<#
.SYNOPSIS Generates a summary of mailbox types, distribution groups, and M365 groups in Exchange Online. .DESCRIPTION Counts mailboxes by type (User, Shared, Room, Equipment), distribution groups, and Microsoft 365 (Unified) groups across the tenant. Provides a high-level inventory useful for M365 assessments, migration planning, and tenant health reviews. Requires ExchangeOnlineManagement module and an active Exchange Online connection. .PARAMETER OutputPath Optional path to export results as CSV. If not specified, results are returned to the pipeline. .EXAMPLE PS> . .\Common\Connect-Service.ps1 PS> Connect-Service -Service ExchangeOnline PS> .\Exchange-Online\Get-MailboxSummary.ps1 Displays a summary of all mailbox types, distribution groups, and M365 groups. .EXAMPLE PS> .\Exchange-Online\Get-MailboxSummary.ps1 -OutputPath '.\mailbox-summary.csv' Exports the mailbox summary to a CSV file for client reporting. .EXAMPLE PS> .\Exchange-Online\Get-MailboxSummary.ps1 -Verbose Displays a mailbox summary with detailed progress messages. #> [CmdletBinding()] param( [Parameter()] [ValidateNotNullOrEmpty()] [string]$OutputPath ) $ErrorActionPreference = 'Stop' # Verify EXO connection try { $null = Get-OrganizationConfig -ErrorAction Stop } catch { Write-Error "Not connected to Exchange Online. Run Connect-Service -Service ExchangeOnline first." return } # Retrieve all mailboxes Write-Verbose "Retrieving all mailboxes (this may take a moment in large tenants)..." try { $allMailboxes = @(Get-EXOMailbox -ResultSize Unlimited -Properties RecipientTypeDetails) } catch { Write-Error "Failed to retrieve mailboxes: $_" return } # Count mailboxes by type $userMailboxes = @($allMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'UserMailbox' }) $sharedMailboxes = @($allMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'SharedMailbox' }) $roomMailboxes = @($allMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'RoomMailbox' }) $equipmentMailboxes = @($allMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'EquipmentMailbox' }) Write-Verbose "Found $($allMailboxes.Count) total mailboxes: $($userMailboxes.Count) User, $($sharedMailboxes.Count) Shared, $($roomMailboxes.Count) Room, $($equipmentMailboxes.Count) Equipment" # Retrieve distribution groups Write-Verbose "Retrieving distribution groups..." try { $distributionGroups = @(Get-DistributionGroup -ResultSize Unlimited) } catch { Write-Warning "Failed to retrieve distribution groups: $_" $distributionGroups = @() } # Retrieve Microsoft 365 groups Write-Verbose "Retrieving Microsoft 365 groups..." try { $m365Groups = @(Get-UnifiedGroup -ResultSize Unlimited) } catch { Write-Warning "Failed to retrieve Microsoft 365 groups: $_" $m365Groups = @() } # Calculate total items via mailbox statistics $totalItemsDisplay = 'N/A' try { Write-Verbose "Retrieving mailbox statistics for item counts..." $totalItemCount = 0 $statsAvailable = $true foreach ($mbx in $allMailboxes) { try { $stats = Get-EXOMailboxStatistics -Identity $mbx.ExchangeObjectId -ErrorAction Stop if ($null -ne $stats.ItemCount) { $totalItemCount += $stats.ItemCount } } catch { $statsAvailable = $false } } if ($statsAvailable -and $allMailboxes.Count -gt 0) { $totalItemsDisplay = $totalItemCount.ToString() } } catch { Write-Warning "Failed to retrieve mailbox statistics: $_" } # Build summary output $results = @( [PSCustomObject]@{ Metric = 'TotalMailboxes' Count = $allMailboxes.Count } [PSCustomObject]@{ Metric = 'UserMailboxes' Count = $userMailboxes.Count } [PSCustomObject]@{ Metric = 'SharedMailboxes' Count = $sharedMailboxes.Count } [PSCustomObject]@{ Metric = 'RoomMailboxes' Count = $roomMailboxes.Count } [PSCustomObject]@{ Metric = 'EquipmentMailboxes' Count = $equipmentMailboxes.Count } [PSCustomObject]@{ Metric = 'DistributionGroups' Count = $distributionGroups.Count } [PSCustomObject]@{ Metric = 'M365Groups' Count = $m365Groups.Count } [PSCustomObject]@{ Metric = 'TotalItems' Count = $totalItemsDisplay } ) Write-Verbose "Summary complete: $($allMailboxes.Count) mailboxes, $($distributionGroups.Count) DLs, $($m365Groups.Count) M365 groups" if ($OutputPath) { $results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 Write-Output "Exported mailbox summary to $OutputPath" } else { Write-Output $results } |