-
Notifications
You must be signed in to change notification settings - Fork 247
ASD Mail Flow Configuration Check
The asd-mailflow-get.ps1 script validates Exchange Online mail flow configuration against the Australian Signals Directorate (ASD) Blueprint for Secure Cloud requirements. It performs automated compliance checks and generates detailed reports.
Version: 1.0
Author: CIAOPS
Date: 11-12-2025
- ✅ 13 Automated Compliance Checks - Validates all mail flow settings against ASD Blueprint
- 📊 Interactive HTML Report - Professional compliance dashboard with visual indicators
- 📁 CSV Export - Optional structured data export for further analysis
- 📝 Detailed Logging - Optional verbose logging for troubleshooting
- 🔄 Live Baseline Updates - Downloads latest requirements from GitHub
- 🎨 Color-Coded Console Output - Easy-to-read terminal feedback
- 🔒 Permission Validation - Checks user permissions before execution
- ExchangeOnlineManagement - Microsoft's official Exchange Online module
# Install if not already present
Install-Module -Name ExchangeOnlineManagement -Scope CurrentUserThe script requires read-only access to Exchange Online organization configuration. One of the following roles is required:
- Exchange Administrator
- Global Administrator
- Global Reader
- View-Only Organization Management
- Compliance Administrator
- PowerShell 5.1 or PowerShell 7.x
- Internet connection (for baseline download)
- Windows, macOS, or Linux
The script validates the following 13 settings:
- PlusAddressingEnabled - Plus addressing feature ([email protected])
- SendFromAliasesEnabled - Sending from email aliases
- SmtpClientAuthenticationDisabled - SMTP client authentication protocol
- AllowLegacyTLSClients - Legacy TLS (1.0/1.1) client support
- ReplyAllStormProtectionEnabled - Storm protection feature
- ReplyAllStormProtectionMinimumRecipients - Minimum recipient threshold (2500)
- ReplyAllStormProtectionMinimumReplies - Minimum reply-all threshold (10)
- ReplyAllStormBlockDurationHours - Block duration (6 hours)
- MessageRecallEnabled - Message recall feature
- RecallReadMessagesEnabled - Allow recalling read messages
- MessageRecallAlertRecipientsEnabled - Recipient alerts for recalls
- MessageRecallAlertRecipientsReadMessagesOnlyEnabled - Alert only for read messages
- MessageRecallMaxAgeInDays - Maximum age for recallable messages (1 day)
.\asd-mailflow-get.ps1Behavior:
- Connects to Exchange Online (prompts for authentication if needed)
- Downloads latest baseline from GitHub
- Performs 13 compliance checks
- Generates HTML report in parent directory
- Opens report in default browser
.\asd-mailflow-get.ps1 -ExportToCSVOutput:
- HTML report (automatic)
- CSV file with compliance data
.\asd-mailflow-get.ps1 -DetailedLoggingGenerates:
- HTML report
- Detailed log file with timestamps and diagnostic information
.\asd-mailflow-get.ps1 -BaselinePath "C:\Baselines\custom-mailflow.json"Use a local baseline file instead of downloading from GitHub.
.\asd-mailflow-get.ps1 -ExportToCSV -CSVPath "C:\Reports\compliance.csv" -DetailedLogging -LogPath "C:\Logs\mailflow.log"Specify custom locations for all output files.
.\asd-mailflow-get.ps1 -ExportToCSV -DetailedLogging -BaselinePath ".\baselines\production.json"| Parameter | Type | Required | Description |
|---|---|---|---|
-ExportToCSV |
Switch | No | Export results to CSV file |
-CSVPath |
String | No | Custom path for CSV export (default: parent directory with timestamp) |
-BaselinePath |
String | No | Path or URL to baseline JSON file (default: GitHub URL) |
-DetailedLogging |
Switch | No | Enable detailed logging to file |
-LogPath |
String | No | Custom path for log file (default: parent directory with timestamp) |
All files are created in the parent directory by default (one level up from script location).
Filename: asd-mailflow-get-YYYYMMDD-HHMMSS.html
Contents:
- Executive summary with compliance percentage
- Visual status cards (Total, Passed, Failed, Compliance %)
- Organization information
- Detailed results table with color-coded status
- Links to ASD Blueprint documentation
Filename: asd-mailflow-get-YYYYMMDD-HHMMSS.csv
Columns:
- Setting
- Description
- CurrentValue
- RequiredValue
- Status (PASS/FAIL)
Filename: asd-mailflow-get-YYYYMMDD-HHMMSS.log
Contents:
- Timestamped events
- Baseline loading details
- Check results
- Error messages and stack traces
The script downloads the latest baseline from:
https://raw.githubusercontent.com/directorcia/bp/main/ASD/Exchange-Online/Settings/mailflow.json
{
"metadata": {
"sourceUrl": "https://blueprint.asd.gov.au/configuration/exchange-online/settings/mail-flow/",
"generatedAt": "2025-11-12"
},
"general": {
"plusAddressingEnabled": false,
"sendFromAliasesEnabled": false
},
"security": {
"smtpAuthProtocolEnabled": false,
"legacyTlsClientsAllowed": false
},
"replyAllStormProtection": {
"enabled": true,
"minimumRecipients": 2500,
"minimumReplyAlls": 10,
"blockDurationHours": 6
},
"messageRecall": {
"enabled": true,
"allowRecallReadMessages": true,
"enableRecipientAlerts": true,
"alertReadMessagesOnly": true,
"maxAgeDays": 1
}
}You can create custom baseline files for different environments:
Development Environment:
{
"messageRecall": {
"maxAgeDays": 7
}
}Production Environment:
{
"messageRecall": {
"maxAgeDays": 1
}
}- Loads script parameters
- Sets default file paths
- Initializes logging (if enabled)
- Displays script banner
- Downloads baseline from GitHub (or loads local file)
- Validates JSON schema
- Falls back to built-in defaults if download fails
- Maps JSON properties to PowerShell requirements
- Checks for ExchangeOnlineManagement module
- Tests existing Exchange Online connection
- Connects to Exchange Online if needed
- Validates user permissions
- Retrieves
Get-OrganizationConfigdata - Retrieves
Get-TransportConfigdata (for Reply-All Storm Protection) - Extracts all 13 mail flow settings
- Stores current values for comparison
Important: Reply-All Storm Protection settings are retrieved from
Get-TransportConfig, notGet-OrganizationConfig. The property names use "Detection" rather than "Protection":
ReplyAllStormProtectionEnabledReplyAllStormDetectionMinimumRecipientsReplyAllStormDetectionMinimumRepliesReplyAllStormBlockDurationHours
- Compares each setting against baseline
- Evaluates boolean, integer, and string values
- Handles null values appropriately:
-
nullboolean values treated asfalse(disabled) -
nullnumeric values treated as0 - Exception:
SmtpClientAuthenticationDisablednull treated astrue
-
- Records PASS/FAIL status for each check
- Logs results (if detailed logging enabled)
- Calculates compliance percentage
- Displays results in console (color-coded)
- Generates HTML report
- Exports CSV (if requested)
- Opens HTML report in browser
- Completes progress indicators
- Writes final log entries
- Returns results object
The script retrieves settings from two different Exchange Online cmdlets:
| Setting Category | Cmdlet | Notes |
|---|---|---|
| General Settings | Get-OrganizationConfig |
Plus addressing, aliases |
| Security Settings | Get-TransportConfig |
SMTP auth (uses OrganizationConfig for legacy TLS) |
| Reply-All Storm Protection | Get-TransportConfig |
Critical: Uses "Detection" in property names |
| Message Recall | Get-OrganizationConfig |
All message recall settings |
Exchange Online may return null for settings that are not explicitly configured but have default behavior:
# Boolean settings - null treated as False (disabled)
$plusAddressingValue = if ($null -eq $orgConfig.PlusAddressingEnabled) { $false } else { $orgConfig.PlusAddressingEnabled }
# Exception: SMTP Auth Disabled - null treated as True (auth is disabled by default)
$smtpAuthDisabledValue = if ($null -eq $orgConfig.SmtpClientAuthenticationDisabled) { $true } else { $orgConfig.SmtpClientAuthenticationDisabled }
# Numeric settings - null treated as 0
$replyAllStormMinRecipientsValue = if ($null -eq $transportConfig.ReplyAllStormDetectionMinimumRecipients) { 0 } else { $transportConfig.ReplyAllStormDetectionMinimumRecipients }This ensures accurate reporting instead of showing "Not set" when values have default behaviors.
========================================
ASD Mail Flow Settings Check
========================================
Baseline: GitHub (latest)
Location: https://raw.githubusercontent.com/directorcia/bp/main/ASD/Exchange-Online/Settings/mailflow.json
Output: C:\downloads\source
Downloading baseline settings from: https://...
✓ Baseline loaded successfully from GitHub.
Checking for ExchangeOnlineManagement module...
ExchangeOnlineManagement module already loaded.
Checking Exchange Online connection...
Already connected to Exchange Online.
Validating Exchange Online permissions...
Permission validation passed.
Retrieving organization mail flow configuration...
Organization configuration retrieved: Contoso Ltd
Retrieving transport configuration...
Transport configuration retrieved.
Checking settings against ASD Blueprint requirements...
========================================
CHECK RESULTS
========================================
[✓] PlusAddressingEnabled
Description : Allow plus addressing ([email protected])
Current : False
Required : False
Status : PASS
[✓] ReplyAllStormProtectionEnabled
Description : Enable reply all storm protection
Current : True
Required : True
Status : PASS
[✓] ReplyAllStormProtectionMinimumRecipients
Description : Minimum recipients to trigger protection
Current : 2500
Required : 2500
Status : PASS
========================================
SUMMARY
========================================
Total Checks : 13
Passed : 13
Failed : 0
Compliance : 100%
Status : COMPLIANT ✓
========================================
Generating HTML report...
HTML report generated: C:\downloads\asd-mailflow-get-20251112-143022.html
Opening report in default browser...
Script completed successfully.
[✗] SmtpClientAuthenticationDisabled
Description : SMTP client authentication (should be disabled)
Current : False
Required : True
Status : FAIL
========================================
SUMMARY
========================================
Total Checks : 13
Passed : 11
Failed : 2
Compliance : 84.62%
Status : NON-COMPLIANT ✗
========================================
-
Header
- Report title
- Subtitle
- Generation timestamp
-
Summary Cards
- Total Checks (blue)
- Passed Checks (green)
- Failed Checks (red)
- Compliance Percentage (green/red based on status)
-
Organization Information
- Organization display name
- Organization identity
- Baseline source (GitHub/Local/Built-in)
-
Detailed Results Table
- Status badge (✓ PASS / ✗ FAIL)
- Setting name
- Description
- Current value
- Required value
-
Overall Status Banner
- COMPLIANT (green) or NON-COMPLIANT (red)
- Summary text
-
Footer
- Link to ASD Blueprint documentation
- Link to security controls explanation
- Responsive Design - Adapts to screen size
- Print-Friendly - Clean layout for PDF generation
- Hover Effects - Interactive card animations
- Color Coding - Visual status indicators
- Professional Styling - Gradient backgrounds and shadows
Error: ExchangeOnlineManagement module not found!
Solution:
Install-Module -Name ExchangeOnlineManagement -Scope CurrentUserError: Failed to connect to Exchange Online
Solutions:
- Ensure internet connectivity
- Verify Microsoft 365 credentials
- Check for service outages
- Disable proxy if causing issues
Error: ❌ INSUFFICIENT PERMISSIONS
Solution:
- Contact Exchange Online administrator
- Request one of the required roles:
- Exchange Administrator
- Global Administrator
- Global Reader
- View-Only Organization Management
- Compliance Administrator
- Wait 5-10 minutes for role assignment propagation
- Re-run the script
Error: Failed to download or parse baseline from URL
Behavior:
- Script continues with built-in ASD Blueprint defaults
- Warning message displayed
- No impact on script execution
Manual Solution:
# Download baseline manually and use local file
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/directorcia/bp/main/ASD/Exchange-Online/Settings/mailflow.json" -OutFile ".\mailflow.json"
.\asd-mailflow-get.ps1 -BaselinePath ".\mailflow.json"Issue: Report shows "Not set" for configured settings
Cause: Exchange Online returns null for settings with default values rather than explicit false or 0.
Resolution: Script now handles null values appropriately:
- Boolean settings:
null→false - Numeric settings:
null→0 - Exception:
SmtpClientAuthenticationDisabledtreatsnull→true
This was fixed in version 1.0 to ensure accurate compliance reporting.
Issue: Reply-All Storm Protection settings show as "Not set" even when configured
Cause: These settings are in Get-TransportConfig, not Get-OrganizationConfig
Property Names:
-
ReplyAllStormProtectionEnabled(in TransportConfig) -
ReplyAllStormDetectionMinimumRecipients(note: "Detection" not "Protection") -
ReplyAllStormDetectionMinimumReplies(note: "Detection" not "Protection") -
ReplyAllStormBlockDurationHours(in TransportConfig)
Resolution: Script now correctly retrieves these settings from Get-TransportConfig with the correct property names.
Issue: Detailed logging enabled but no log file
Check:
- Verify write permissions to output directory
- Check disk space
- Review any error messages in console
Run automated compliance checks using Windows Task Scheduler or cron:
# Windows Task Scheduler command
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\asd-mailflow-get.ps1" -ExportToCSV -DetailedLoggingExport CSV data for ingestion into monitoring platforms:
$results = .\asd-mailflow-get.ps1 -ExportToCSV
$failed = Import-Csv ".\asd-mailflow-get-*.csv" | Where-Object { $_.Status -eq "FAIL" }
if ($failed) {
# Send alert to monitoring system
Send-Alert -Message "Mail flow compliance failures detected" -Data $failed
}Check multiple Exchange Online tenants:
$tenants = @("tenant1.onmicrosoft.com", "tenant2.onmicrosoft.com")
foreach ($tenant in $tenants) {
Write-Host "Checking tenant: $tenant"
Connect-ExchangeOnline -UserPrincipalName "admin@$tenant" -ShowBanner:$false
.\asd-mailflow-get.ps1 -ExportToCSV
Disconnect-ExchangeOnline -Confirm:$false
}Create organization-specific baselines:
# Create custom baseline
$customBaseline = @{
messageRecall = @{
enabled = $true
maxAgeDays = 3 # Organization-specific requirement
}
} | ConvertTo-Json -Depth 5
$customBaseline | Out-File ".\custom-baseline.json"
# Use custom baseline
.\asd-mailflow-get.ps1 -BaselinePath ".\custom-baseline.json"| Function | Purpose |
|---|---|
Write-Log |
Writes timestamped entries to log file |
Write-ColorOutput |
Displays color-coded console messages |
Get-BaselineValue |
Safely extracts values from JSON baseline |
Test-BaselineSchema |
Validates JSON structure |
Get-BaselineSettings |
Loads and parses baseline configuration |
Test-ExchangeModule |
Checks and loads Exchange Online module |
Connect-EXO |
Establishes Exchange Online connection |
Test-ExchangePermissions |
Validates user permissions |
Test-Setting |
Compares individual setting against baseline |
New-HTMLReport |
Generates professional compliance report |
Invoke-MailFlowCheck |
Main orchestration function |
| Variable | Scope | Description |
|---|---|---|
$script:BaselinePath |
Script | Baseline file path or URL |
$script:baselineLoaded |
Script | Baseline load success indicator |
$script:HTMLPath |
Script | HTML report output path |
$script:LogPath |
Script | Log file path |
$script:DetailedLogging |
Script | Logging enabled flag |
- Try-Catch Blocks - Wrap all external operations
- ErrorAction Stop - Explicit error handling
- Graceful Degradation - Falls back to defaults when possible
- User-Friendly Messages - Clear error descriptions with solutions
- Detailed Stack Traces - Available in log files
- Run weekly or monthly compliance checks
- Schedule checks after configuration changes
- Document compliance trends over time
- Review baseline updates quarterly
- Test baseline changes in non-production first
- Version control custom baselines
- Use service accounts with minimal permissions
- Store credentials securely (not in scripts)
- Review logs for unauthorized changes
- Audit compliance check results
- Archive HTML reports for compliance audits
- Share reports with security teams
- Track remediation of failed checks
- Export CSV for long-term analysis
- ASD Blueprint: https://blueprint.asd.gov.au/configuration/exchange-online/settings/mail-flow/
- Script Repository: https://github.com/directorcia/office365
- Script Documentation: https://github.com/directorcia/Office365/wiki/ASD-Mail-Flow-Configuration-Check
- Security Controls: https://github.com/directorcia/bp/wiki/Exchange-Online-Mail-Flow-Security-Controls
- Module Documentation: https://docs.microsoft.com/en-us/powershell/exchange/exchange-online-powershell
- Get-OrganizationConfig: https://docs.microsoft.com/en-us/powershell/module/exchange/get-organizationconfig
- Get-TransportConfig: https://docs.microsoft.com/en-us/powershell/module/exchange/get-transportconfig
- Connect-ExchangeOnline: https://docs.microsoft.com/en-us/powershell/module/exchange/connect-exchangeonline
| Version | Date | Changes |
|---|---|---|
| 1.0 | 2025-11-12 | Initial release with 13 compliance checks, HTML reporting, CSV export, and detailed logging. Fixed null value handling and Reply-All Storm Protection detection. |
For issues, questions, or contributions:
- GitHub Issues: https://github.com/directorcia/office365/issues
- Wiki: https://github.com/directorcia/office365/wiki
- Community: Engage with the CIAOPS community
This script is provided as-is for use in compliance checking and auditing of Exchange Online mail flow configurations against ASD Blueprint requirements.
Last Updated: November 12, 2025
Script Version: 1.0
Author: CIAOPS