Src/Private/Get-AbrExoQuarantine.ps1
|
function Get-AbrExoQuarantine { <# .SYNOPSIS Documents Exchange Online quarantine policies and provides a quarantine summary snapshot. .NOTES Version: 0.1.0 Author: Pai Wei Sing #> [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory)] [string]$TenantId ) begin { Write-PScriboMessage -Message "Collecting Exchange Online Quarantine configuration for $TenantId." Show-AbrDebugExecutionTime -Start -TitleMessage 'Quarantine' } process { Section -Style Heading2 'Quarantine Policies' { Paragraph "The following section documents quarantine policies that control end-user notification and release permissions for quarantined messages in tenant $TenantId." BlankLine #region Quarantine Policies try { Write-Host " - Retrieving quarantine policies..." $QuarantinePolicies = Get-QuarantinePolicy -ErrorAction Stop | Sort-Object QuarantinePolicyType, Name if ($QuarantinePolicies -and @($QuarantinePolicies).Count -gt 0) { $QpObj = [System.Collections.ArrayList]::new() foreach ($Policy in $QuarantinePolicies) { $qpInObj = [ordered] @{ 'Policy Name' = $Policy.Name 'Policy Type' = $Policy.QuarantinePolicyType 'End-User Spam Notifications' = $Policy.EndUserSpamNotificationFrequency -gt 0 'Notification Frequency (days)' = if ($Policy.EndUserSpamNotificationFrequency) { $Policy.EndUserSpamNotificationFrequency } else { 'Disabled' } 'End-User Quarantine Access' = $Policy.EndUserQuarantinePermissionsValue 'Release to All Allowed' = ($Policy.EndUserQuarantinePermissionsValue -band 4) -gt 0 'Delete Allowed' = ($Policy.EndUserQuarantinePermissionsValue -band 8) -gt 0 'Preview Allowed' = ($Policy.EndUserQuarantinePermissionsValue -band 2) -gt 0 } $QpObj.Add([pscustomobject](ConvertTo-HashToYN $qpInObj)) | Out-Null } $null = (& { if ($HealthCheck.ExchangeOnline.AntiSpam) { # Flag policies that allow users to release messages to all recipients $null = ($QpObj | Where-Object { $_.'Release to All Allowed' -eq 'Yes' } | Set-Style -Style Warning | Out-Null) } }) $QpTableParams = @{ Name = "Quarantine Policies - $TenantId"; List = $false; ColumnWidths = 18, 14, 12, 13, 13, 10, 10, 10 } if ($Report.ShowTableCaptions) { $QpTableParams['Caption'] = "- $($QpTableParams.Name)" } if ($QpObj.Count -gt 0) { $QpObj | Table @QpTableParams } $script:ExcelSheets['Quarantine Policies'] = $QpObj } else { Paragraph "No custom quarantine policies found. Default quarantine policies (AdminOnlyAccessPolicy, DefaultFullAccessPolicy) are in use." } } catch { Write-ExoError 'Quarantine' "Unable to retrieve quarantine policies: $($_.Exception.Message)" Paragraph "Unable to retrieve quarantine policy data: $($_.Exception.Message)" } #endregion #region Quarantine Message Summary (InfoLevel 2) if ($InfoLevel.AntiSpam -ge 2) { try { Write-Host " - Retrieving quarantine message summary..." # Get counts by type for the last 30 days - use a short window to avoid timeouts $QuarantineMessages = Get-QuarantineMessage -PageSize 100 -ErrorAction SilentlyContinue if ($QuarantineMessages) { $QmSummary = $QuarantineMessages | Group-Object -Property Type | Sort-Object Count -Descending $QmObj = [System.Collections.ArrayList]::new() foreach ($Group in $QmSummary) { $qmInObj = [ordered] @{ 'Message Type' = $Group.Name 'Count' = $Group.Count } $QmObj.Add([pscustomobject]$qmInObj) | Out-Null } Section -Style Heading3 'Quarantine Message Snapshot (last 100)' { Paragraph "The following table shows a snapshot of the most recent 100 quarantined messages grouped by type in tenant $TenantId." BlankLine $QmTableParams = @{ Name = "Quarantine Snapshot - $TenantId"; List = $false; ColumnWidths = 60, 40 } if ($Report.ShowTableCaptions) { $QmTableParams['Caption'] = "- $($QmTableParams.Name)" } if ($QmObj.Count -gt 0) { $QmObj | Table @QmTableParams } } } } catch { # Quarantine message retrieval is best-effort, don't fail the section Write-AbrDebugLog "Quarantine message snapshot skipped: $($_.Exception.Message)" 'DEBUG' 'Quarantine' } } #endregion } } end { Show-AbrDebugExecutionTime -End -TitleMessage 'Quarantine' } } |