Src/Private/Get-AbrExoMailboxes.ps1
|
function Get-AbrExoMailboxes { <# .SYNOPSIS Documents Exchange Online mailbox inventory, shared mailboxes, and resource mailboxes. .NOTES Version: 0.1.0 Author: Pai Wei Sing #> [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory)] [string]$TenantId ) begin { Write-PScriboMessage -Message "Collecting Exchange Online Mailbox information for $TenantId." Show-AbrDebugExecutionTime -Start -TitleMessage 'Mailboxes' } process { Section -Style Heading2 'Mailbox Inventory' { Paragraph "The following section documents mailbox inventory and configuration for tenant $TenantId." BlankLine #region Mailbox Summary try { Write-Host " - Retrieving mailbox inventory..." $AllMailboxes = Get-Mailbox -ResultSize Unlimited -ErrorAction Stop $UserMailboxes = @($AllMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'UserMailbox' }) $SharedMailboxes = @($AllMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'SharedMailbox' }) $RoomMailboxes = @($AllMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'RoomMailbox' }) $EquipMailboxes = @($AllMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'EquipmentMailbox' }) $GuestMailboxes = @($AllMailboxes | Where-Object { $_.RecipientTypeDetails -eq 'GuestMailbox' }) $SummaryObj = [System.Collections.ArrayList]::new() $summaryInObj = [ordered] @{ 'Total Mailboxes' = @($AllMailboxes).Count 'User Mailboxes' = $UserMailboxes.Count 'Shared Mailboxes' = $SharedMailboxes.Count 'Room Mailboxes' = $RoomMailboxes.Count 'Equipment Mailboxes' = $EquipMailboxes.Count 'Guest Mailboxes' = $GuestMailboxes.Count } $SummaryObj.Add([pscustomobject]$summaryInObj) | Out-Null $SumTableParams = @{ Name = "Mailbox Summary - $TenantId"; List = $true; ColumnWidths = 50, 50 } if ($Report.ShowTableCaptions) { $SumTableParams['Caption'] = "- $($SumTableParams.Name)" } $SummaryObj | Table @SumTableParams } catch { Write-ExoError 'Mailboxes' "Unable to retrieve mailboxes: $($_.Exception.Message)" Paragraph "Unable to retrieve mailbox data: $($_.Exception.Message)" return } #endregion #region User Mailbox Detail (InfoLevel 2) if ($InfoLevel.Mailboxes -ge 2 -and $UserMailboxes.Count -gt 0) { Section -Style Heading3 'User Mailboxes' { Paragraph "The following $($UserMailboxes.Count) user mailbox(es) are configured in tenant $TenantId." BlankLine $MbxObj = [System.Collections.ArrayList]::new() foreach ($Mbx in ($UserMailboxes | Sort-Object DisplayName)) { $mbxInObj = [ordered] @{ 'Display Name' = $Mbx.DisplayName 'UPN' = $Mbx.UserPrincipalName 'Primary SMTP' = $Mbx.PrimarySmtpAddress 'Archive Enabled' = $Mbx.ArchiveStatus -ne 'None' 'Litigation Hold' = $Mbx.LitigationHoldEnabled 'Single Item Recovery' = $Mbx.SingleItemRecoveryEnabled 'Audit Enabled' = $Mbx.AuditEnabled 'Forwarding Address' = if ($Mbx.ForwardingSmtpAddress) { $Mbx.ForwardingSmtpAddress } elseif ($Mbx.ForwardingAddress) { $Mbx.ForwardingAddress } else { 'None' } 'Deliver & Forward' = $Mbx.DeliverToMailboxAndForward } $MbxObj.Add([pscustomobject](ConvertTo-HashToYN $mbxInObj)) | Out-Null } $null = (& { if ($HealthCheck.ExchangeOnline.Mailboxes) { # Flag mailboxes with external forwarding configured $null = ($MbxObj | Where-Object { $_.'Forwarding Address' -ne 'None' -and $_.'Forwarding Address' -notmatch $script:TenantDomain } | Set-Style -Style Critical | Out-Null) # Flag mailboxes without audit enabled $null = ($MbxObj | Where-Object { $_.'Audit Enabled' -eq 'No' } | Set-Style -Style Warning | Out-Null) } }) $MbxTableParams = @{ Name = "User Mailboxes - $TenantId"; List = $false; ColumnWidths = 14, 18, 17, 7, 8, 8, 8, 14, 6 } if ($Report.ShowTableCaptions) { $MbxTableParams['Caption'] = "- $($MbxTableParams.Name)" } $MbxObj | Table @MbxTableParams $script:ExcelSheets['User Mailboxes'] = $MbxObj } } #endregion #region Shared Mailboxes if ($SharedMailboxes.Count -gt 0) { Section -Style Heading3 'Shared Mailboxes' { Paragraph "The following $($SharedMailboxes.Count) shared mailbox(es) are configured in tenant $TenantId." BlankLine $SharedObj = [System.Collections.ArrayList]::new() foreach ($Mbx in ($SharedMailboxes | Sort-Object DisplayName)) { # Get permissions for this shared mailbox $FullAccessCount = 0 $SendAsCount = 0 try { $FullAccessPerms = Get-MailboxPermission -Identity $Mbx.Identity -ErrorAction SilentlyContinue | Where-Object { $_.AccessRights -contains 'FullAccess' -and -not $_.IsInherited -and $_.User -ne 'NT AUTHORITY\SELF' } $FullAccessCount = @($FullAccessPerms).Count $SendAsPerms = Get-RecipientPermission -Identity $Mbx.Identity -ErrorAction SilentlyContinue | Where-Object { $_.AccessRights -contains 'SendAs' -and $_.Trustee -ne 'NT AUTHORITY\SELF' } $SendAsCount = @($SendAsPerms).Count } catch {} $sharedInObj = [ordered] @{ 'Display Name' = $Mbx.DisplayName 'Primary SMTP' = $Mbx.PrimarySmtpAddress 'Full Access Users' = $FullAccessCount 'Send As Users' = $SendAsCount 'Audit Enabled' = $Mbx.AuditEnabled 'Litigation Hold' = $Mbx.LitigationHoldEnabled 'Forwarding Address' = if ($Mbx.ForwardingSmtpAddress) { $Mbx.ForwardingSmtpAddress } else { 'None' } } $SharedObj.Add([pscustomobject](ConvertTo-HashToYN $sharedInObj)) | Out-Null } $null = (& { if ($HealthCheck.ExchangeOnline.Mailboxes) { $null = ($SharedObj | Where-Object { $_.'Full Access Users' -eq '0' } | Set-Style -Style Warning | Out-Null) $null = ($SharedObj | Where-Object { $_.'Forwarding Address' -ne 'None' } | Set-Style -Style Critical | Out-Null) } }) $SharedTableParams = @{ Name = "Shared Mailboxes - $TenantId"; List = $false; ColumnWidths = 18, 22, 10, 10, 10, 10, 20 } if ($Report.ShowTableCaptions) { $SharedTableParams['Caption'] = "- $($SharedTableParams.Name)" } $SharedObj | Table @SharedTableParams $script:ExcelSheets['Shared Mailboxes'] = $SharedObj } } #endregion #region Resource Mailboxes (Rooms + Equipment) if ($InfoLevel.ResourceMailboxes -ge 1 -and ($RoomMailboxes.Count -gt 0 -or $EquipMailboxes.Count -gt 0)) { Section -Style Heading3 'Resource Mailboxes' { Paragraph "The following resource mailboxes (rooms and equipment) are configured in tenant $TenantId." BlankLine $ResObj = [System.Collections.ArrayList]::new() foreach ($Mbx in (($RoomMailboxes + $EquipMailboxes) | Sort-Object DisplayName)) { $resInObj = [ordered] @{ 'Display Name' = $Mbx.DisplayName 'Type' = $Mbx.RecipientTypeDetails 'Primary SMTP' = $Mbx.PrimarySmtpAddress 'Audit Enabled' = $Mbx.AuditEnabled } $ResObj.Add([pscustomobject](ConvertTo-HashToYN $resInObj)) | Out-Null } $ResTableParams = @{ Name = "Resource Mailboxes - $TenantId"; List = $false; ColumnWidths = 30, 20, 35, 15 } if ($Report.ShowTableCaptions) { $ResTableParams['Caption'] = "- $($ResTableParams.Name)" } $ResObj | Table @ResTableParams $script:ExcelSheets['Resource Mailboxes'] = $ResObj } } #endregion #region Mailboxes with External Forwarding (gap report) try { $ExternalForwardMailboxes = @($AllMailboxes | Where-Object { ($_.ForwardingSmtpAddress -and $_.ForwardingSmtpAddress -notmatch $script:TenantDomain) -or ($_.ForwardingAddress -and $_.ForwardingAddress -notmatch $script:TenantDomain) }) if ($ExternalForwardMailboxes.Count -gt 0) { Section -Style Heading3 'Mailboxes with External Forwarding' { Paragraph "WARNING: The following $($ExternalForwardMailboxes.Count) mailbox(es) are configured to forward email to external addresses. This is a data exfiltration risk and should be reviewed." BlankLine $FwdObj = [System.Collections.ArrayList]::new() foreach ($Mbx in $ExternalForwardMailboxes) { $fwdInObj = [ordered] @{ 'Display Name' = $Mbx.DisplayName 'UPN' = $Mbx.UserPrincipalName 'Forwarding Address' = if ($Mbx.ForwardingSmtpAddress) { $Mbx.ForwardingSmtpAddress } else { $Mbx.ForwardingAddress } 'Deliver & Forward' = $Mbx.DeliverToMailboxAndForward 'Mailbox Type' = $Mbx.RecipientTypeDetails } $FwdObj.Add([pscustomobject](ConvertTo-HashToYN $fwdInObj)) | Out-Null } $null = (& { if ($HealthCheck.ExchangeOnline.Mailboxes) { $null = ($FwdObj | Set-Style -Style Critical | Out-Null) } }) $FwdTableParams = @{ Name = "Mailboxes with External Forwarding - $TenantId"; List = $false; ColumnWidths = 20, 22, 28, 15, 15 } if ($Report.ShowTableCaptions) { $FwdTableParams['Caption'] = "- $($FwdTableParams.Name)" } $FwdObj | Table @FwdTableParams $script:ExcelSheets['External Forwarding'] = $FwdObj } } } catch { Write-ExoError 'Mailboxes' "Unable to check external forwarding: $($_.Exception.Message)" } #endregion } } end { Show-AbrDebugExecutionTime -End -TitleMessage 'Mailboxes' } } |