|
| 1 | +function Invoke-CIPPStandardEXOOutboundSpamLimits { |
| 2 | + <# |
| 3 | + .FUNCTIONALITY |
| 4 | + Internal |
| 5 | + .COMPONENT |
| 6 | + (APIName) EXOOutboundSpamLimits |
| 7 | + .SYNOPSIS |
| 8 | + (Label) Set Exchange Outbound Spam Limits |
| 9 | + .DESCRIPTION |
| 10 | + (Helptext) Configures the outbound spam recipient limits (external per hour, internal per hour, per day) and the action to take when a limit is reached. The 'Set Outbound Spam Alert e-mail' standard is recommended to configure together with this one. |
| 11 | + (DocsDescription) Configures the Exchange Online outbound spam recipient limits for external per hour, internal per hour, and per day, along with the action to take (e.g., BlockUser, Alert) when these limits are exceeded. This helps prevent abuse and manage email flow. Microsoft's recommendations can be found [here.](https://learn.microsoft.com/en-us/defender-office-365/recommended-settings-for-eop-and-office365#eop-outbound-spam-policy-settings) The 'Set Outbound Spam Alert e-mail' standard is recommended to configure together with this one. |
| 12 | + .NOTES |
| 13 | + CAT |
| 14 | + Exchange Standards |
| 15 | + TAG |
| 16 | + "CIS" |
| 17 | + ADDEDCOMPONENT |
| 18 | + {"type":"number","name":"standards.EXOOutboundSpamLimits.RecipientLimitExternalPerHour","label":"External Recipient Limit Per Hour","defaultValue":400} |
| 19 | + {"type":"number","name":"standards.EXOOutboundSpamLimits.RecipientLimitInternalPerHour","label":"Internal Recipient Limit Per Hour","defaultValue":800} |
| 20 | + {"type":"number","name":"standards.EXOOutboundSpamLimits.RecipientLimitPerDay","label":"Daily Recipient Limit","defaultValue":800} |
| 21 | + {"type":"autoComplete","multiple":false,"creatable":false,"name":"standards.EXOOutboundSpamLimits.ActionWhenThresholdReached","label":"Action When Threshold Reached","options":[{"label":"Alert","value":"Alert"},{"label":"Block User","value":"BlockUser"},{"label":"Block user from sending mail for the rest of the day","value":"BlockUserForToday"}]} |
| 22 | + IMPACT |
| 23 | + Low Impact |
| 24 | + ADDEDDATE |
| 25 | + 2025-05-13 |
| 26 | + POWERSHELLEQUIVALENT |
| 27 | + Set-HostedOutboundSpamFilterPolicy |
| 28 | + RECOMMENDEDBY |
| 29 | + "CIPP" |
| 30 | + "CIS" |
| 31 | + UPDATECOMMENTBLOCK |
| 32 | + Run the Tools\Update-StandardsComments.ps1 script to update this comment block |
| 33 | + .LINK |
| 34 | + https://docs.cipp.app/user-documentation/tenant/standards/list-standards/exchange-standards#low-impact |
| 35 | + #> |
| 36 | + |
| 37 | + param($Tenant, $Settings) |
| 38 | + |
| 39 | + # Make sure it handles the frontend being both autocomplete and a text field |
| 40 | + $ActionWhenThresholdReached = $Settings.ActionWhenThresholdReached.value ?? $Settings.ActionWhenThresholdReached |
| 41 | + |
| 42 | + # Input validation |
| 43 | + if ([Int32]$Settings.RecipientLimitExternalPerHour -lt 0 -or [Int32]$Settings.RecipientLimitExternalPerHour -gt 10000) { |
| 44 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'EXOOutboundSpamLimits: Invalid RecipientLimitExternalPerHour parameter set. Must be between 0 and 10000.' -sev Error |
| 45 | + return |
| 46 | + } |
| 47 | + |
| 48 | + if ([Int32]$Settings.RecipientLimitInternalPerHour -lt 0 -or [Int32]$Settings.RecipientLimitInternalPerHour -gt 10000) { |
| 49 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'EXOOutboundSpamLimits: Invalid RecipientLimitInternalPerHour parameter set. Must be between 0 and 10000.' -sev Error |
| 50 | + return |
| 51 | + } |
| 52 | + |
| 53 | + if ([Int32]$Settings.RecipientLimitPerDay -lt 0 -or [Int32]$Settings.RecipientLimitPerDay -gt 10000) { |
| 54 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'EXOOutboundSpamLimits: Invalid RecipientLimitPerDay parameter set. Must be between 0 and 10000.' -sev Error |
| 55 | + return |
| 56 | + } |
| 57 | + |
| 58 | + $ValidActions = @('Alert', 'BlockUser', 'BlockUserForToday') |
| 59 | + if ($ActionWhenThresholdReached -notin $ValidActions) { |
| 60 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'EXOOutboundSpamLimits: Invalid ActionWhenThresholdReached parameter set. Must be one of: Alert, BlockUser, BlockUserForToday.' -sev Error |
| 61 | + return |
| 62 | + } |
| 63 | + |
| 64 | + # Get current settings |
| 65 | + $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-HostedOutboundSpamFilterPolicy' -cmdParams @{Identity = 'Default' } -Select 'RecipientLimitExternalPerHour, RecipientLimitInternalPerHour, RecipientLimitPerDay, ActionWhenThresholdReached' -useSystemMailbox $true | Select-Object -ExcludeProperty *data.type* |
| 66 | + |
| 67 | + # Check if settings are already correct |
| 68 | + $StateIsCorrect = ($CurrentInfo.RecipientLimitExternalPerHour -eq $Settings.RecipientLimitExternalPerHour) -and |
| 69 | + ($CurrentInfo.RecipientLimitInternalPerHour -eq $Settings.RecipientLimitInternalPerHour) -and |
| 70 | + ($CurrentInfo.RecipientLimitPerDay -eq $Settings.RecipientLimitPerDay) -and |
| 71 | + ($CurrentInfo.ActionWhenThresholdReached -eq $ActionWhenThresholdReached) |
| 72 | + |
| 73 | + # Remediation |
| 74 | + If ($Settings.remediate -eq $true) { |
| 75 | + Write-Host 'Time to remediate' |
| 76 | + if ($StateIsCorrect -eq $false) { |
| 77 | + try { |
| 78 | + $null = New-ExoRequest -tenantid $Tenant -cmdlet 'Set-HostedOutboundSpamFilterPolicy' -cmdParams @{ |
| 79 | + Identity = 'Default' |
| 80 | + RecipientLimitExternalPerHour = $Settings.RecipientLimitExternalPerHour |
| 81 | + RecipientLimitInternalPerHour = $Settings.RecipientLimitInternalPerHour |
| 82 | + RecipientLimitPerDay = $Settings.RecipientLimitPerDay |
| 83 | + ActionWhenThresholdReached = $ActionWhenThresholdReached |
| 84 | + } -useSystemMailbox $true |
| 85 | + |
| 86 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Set outbound spam limits: External=$($Settings.RecipientLimitExternalPerHour), Internal=$($Settings.RecipientLimitInternalPerHour), Daily=$($Settings.RecipientLimitPerDay), Action=$($ActionWhenThresholdReached)" -sev Info |
| 87 | + } catch { |
| 88 | + $ErrorMessage = Get-CippException -Exception $_ |
| 89 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Could not set outbound spam limits. $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage |
| 90 | + } |
| 91 | + } else { |
| 92 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Outbound spam limits are already set correctly' -sev Info |
| 93 | + } |
| 94 | + } |
| 95 | + |
| 96 | + # Alert |
| 97 | + if ($Settings.alert -eq $true) { |
| 98 | + if ($StateIsCorrect -eq $true) { |
| 99 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Outbound spam limits are correctly configured: External=$($Settings.RecipientLimitExternalPerHour), Internal=$($Settings.RecipientLimitInternalPerHour), Daily=$($Settings.RecipientLimitPerDay), Action=$($ActionWhenThresholdReached)" -sev Info |
| 100 | + } else { |
| 101 | + Write-StandardsAlert -message 'Outbound spam limits are not configured correctly' -object $CurrentInfo -tenant $Tenant -standardName 'EXOOutboundSpamLimits' -standardId $Settings.standardId |
| 102 | + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Outbound spam limits are not configured correctly' -sev Info |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + # Report |
| 107 | + if ($Settings.report -eq $true) { |
| 108 | + $State = $StateIsCorrect ? $true : $CurrentInfo |
| 109 | + Set-CIPPStandardsCompareField -FieldName 'standards.EXOOutboundSpamLimits' -FieldValue $State -TenantFilter $Tenant |
| 110 | + Add-CIPPBPAField -FieldName 'OutboundSpamLimitsConfigured' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $Tenant |
| 111 | + } |
| 112 | +} |
0 commit comments