Private/Normalize-IdleExchangeOnlineAutoReplyMessage.ps1
|
function Normalize-IdleExchangeOnlineAutoReplyMessage { <# .SYNOPSIS Normalizes Exchange Online auto-reply messages for stable idempotency comparison. .DESCRIPTION Exchange Online may introduce server-side canonicalization when storing automatic reply messages, such as adding HTML/body wrappers, normalizing line endings, or adjusting whitespace. This helper performs minimal, deterministic normalization to ensure that functionally equivalent messages are recognized as identical during idempotency checks. Normalization operations: - Normalize line endings (CRLF to LF) - Remove common HTML wrappers added by Exchange (<html>, <head>, <body>) - Trim leading/trailing whitespace - Normalize consecutive whitespace sequences in HTML (multiple spaces/tabs to single space) This function does NOT sanitize or validate HTML. It only normalizes structural differences introduced by server-side canonicalization. .PARAMETER Message The auto-reply message string to normalize (plain text or HTML). .OUTPUTS System.String - The normalized message string. .EXAMPLE $normalized = Normalize-IdleExchangeOnlineAutoReplyMessage -Message $currentMessage if ($normalized -eq (Normalize-IdleExchangeOnlineAutoReplyMessage -Message $desiredMessage)) { # Messages are functionally equivalent } .NOTES This is a private helper function used by the ExchangeOnline provider for idempotency checks. #> [CmdletBinding()] [OutputType([string])] param( [Parameter()] [AllowEmptyString()] [AllowNull()] [string] $Message ) if ([string]::IsNullOrEmpty($Message)) { return '' } # Start with the original message $normalized = $Message # 1. Normalize line endings: CRLF -> LF $normalized = $normalized -replace "`r`n", "`n" $normalized = $normalized -replace "`r", "`n" # 2. Remove common HTML wrappers that Exchange may add # Remove <!DOCTYPE ...> declarations $normalized = $normalized -replace '(?i)<!DOCTYPE[^>]*>', '' # Remove <html> opening and closing tags (with optional attributes) $normalized = $normalized -replace '(?i)<html[^>]*>', '' $normalized = $normalized -replace '(?i)</html>', '' # Remove <head> wrapper tags while preserving their inner content $normalized = $normalized -replace '(?is)<head[^>]*>\s*(.*?)\s*</head>', '$1' # Remove <body> opening and closing tags (with optional attributes) $normalized = $normalized -replace '(?i)<body[^>]*>', '' $normalized = $normalized -replace '(?i)</body>', '' # 3. Trim leading/trailing whitespace (including newlines) $normalized = $normalized.Trim() # 4. Normalize whitespace conservatively # Only collapse truly excessive whitespace that Exchange commonly adds # This is conservative to avoid making intentionally different messages compare equal # NOTE: This normalization is ONLY used for idempotency comparison, not for modifying # the actual message sent to Exchange. The original message formatting is preserved. # Normalize 3+ consecutive spaces/tabs to 2 (preserves intentional double-spacing) # This handles Exchange adding extra whitespace without collapsing intentional formatting $normalized = $normalized -replace '[ \t]{3,}', ' ' # 5. Normalize excessive empty lines (4+ consecutive newlines to 3) # This is very conservative - only removes truly excessive blank lines # Preserves intentional spacing while handling Exchange-added excessive gaps $normalized = $normalized -replace '\n{4,}', "`n`n`n" # 6. Final trim to remove any whitespace introduced by previous operations $normalized = $normalized.Trim() return $normalized } |