From cd9dd12839c702e3a6396f028d360f6e9fffb85a Mon Sep 17 00:00:00 2001 From: David Paulson Date: Fri, 9 Feb 2024 09:12:27 -0600 Subject: [PATCH 1/6] Prevent Divide By Zero --- .../Exchange/Get-MailboxStatisticsOnDatabase.ps1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Search/Troubleshoot-ModernSearch/Exchange/Get-MailboxStatisticsOnDatabase.ps1 b/Search/Troubleshoot-ModernSearch/Exchange/Get-MailboxStatisticsOnDatabase.ps1 index c6b7703f45..9dda5a058b 100644 --- a/Search/Troubleshoot-ModernSearch/Exchange/Get-MailboxStatisticsOnDatabase.ps1 +++ b/Search/Troubleshoot-ModernSearch/Exchange/Get-MailboxStatisticsOnDatabase.ps1 @@ -38,7 +38,11 @@ function Get-MailboxStatisticsOnDatabase { if ($totalBigFunnelSearchableItems -ne 0) { $fullIndexPercentage = [Math]::Round((($_.BigFunnelIndexedCount / $totalBigFunnelSearchableItems) * 100), 2) - $notPartIndexPercentage = [Math]::Round((($_.BigFunnelIndexedCount / ($totalBigFunnelSearchableItems - $_.BigFunnelPartiallyIndexedCount)) * 100), 2) + $divideBy = $totalBigFunnelSearchableItems - $_.BigFunnelPartiallyIndexedCount + + if ($divideBy -ne 0) { + $notPartIndexPercentage = [Math]::Round((($_.BigFunnelIndexedCount / $divideBy) * 100), 2) + } } $mailboxStatisticsList.Add([PSCustomObject]@{ From 369562e2c7b3f8df3a7425782c9d3ec532595998 Mon Sep 17 00:00:00 2001 From: David Paulson Date: Fri, 9 Feb 2024 08:34:24 -0600 Subject: [PATCH 2/6] Check for misconfigured EXO Connector --- ...ke-AnalyzerFrequentConfigurationIssues.ps1 | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 b/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 index 0267ca064e..d75bb69b41 100644 --- a/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 +++ b/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 @@ -263,4 +263,72 @@ function Invoke-AnalyzerFrequentConfigurationIssues { Details = $exchangeInformation.RegistryValues.DisablePreservation } Add-AnalyzedResultInformation @params + + # Detect Send Connector sending to EXO + $exoConnector = New-Object System.Collections.Generic.List[object] + $sendConnectors = $exchangeInformation.ExchangeConnectors | Where-Object { $_.ConnectorType -eq "Send" } + + foreach ($sendConnector in $sendConnectors) { + $smartHostMatch = ($sendConnector.SmartHosts -like "*.mail.protection.outlook.com").Count -gt 0 + $dnsMatch = $sendConnector.SmartHosts -eq 0 -and ($sendConnector.AddressSpaces.Address -like "*.mail.onmicrosoft.com").Count -gt 0 + + if ($dnsMatch -or $smartHostMatch) { + $exoConnector.Add($sendConnector) + } + } + + $params = $baseParams + @{ + Name = "EXO Connector Present" + Details = ($exoConnector.Count -gt 0) + } + Add-AnalyzedResultInformation @params + $showMoreInfo = $false + + foreach ($connector in $exoConnector) { + # Misconfigured connector is if TLSCertificateName is not set or CloudServicesMailEnabled not set to true + if ($connector.CloudEnabled -eq $false -or + $connector.CertificateDetails.TlsCertificateNameStatus -eq "TlsCertificateNameEmpty") { + $params = $baseParams + @{ + Name = "Send Connector - $($connector.Identity.ToString())" + Details = "Misconfigured to to send authenticated internal mail to M365." + + "`r`n`t`t`tCloudServicesMailEnabled: $($connector.CloudEnabled)" + + "`r`n`t`t`tTLSCertificateName set: $($connector.CertificateDetails.TlsCertificateNameStatus -ne "TlsCertificateNameEmpty")" + DisplayCustomTabNumber = 2 + DisplayWriteType = "Red" + } + Add-AnalyzedResultInformation @params + $showMoreInfo = $true + } + + if ($connector.TlsAuthLevel -ne "DomainValidation") { + $params = $baseParams + @{ + Name = "Send Connector - $($connector.Identity.ToString())" + Details = "TlsAuthLevel not set to DomainValidation" + DisplayCustomTabNumber = 2 + DisplayWriteType = "Yellow" + } + Add-AnalyzedResultInformation @params + $showMoreInfo = $true + } + + if ($connector.TlsDomain -ne "mail.protection.outlook.com") { + $params = $baseParams + @{ + Name = "Send Connector - $($connector.Identity.ToString())" + Details = "TLSDomain not set to mail.protection.outlook.com" + DisplayCustomTabNumber = 2 + DisplayWriteType = "Yellow" + } + Add-AnalyzedResultInformation @params + $showMoreInfo = $true + } + } + + if ($showMoreInfo) { + $params = $baseParams + @{ + Details = "More Information: https://aka.ms/HC-ExoConnectorIssue" + DisplayWriteType = "Yellow" + DisplayCustomTabNumber = 2 + } + Add-AnalyzedResultInformation @params + } } From b0d895cc842bbdd90bd8622d356aaea4cf9624ff Mon Sep 17 00:00:00 2001 From: David Paulson Date: Fri, 9 Feb 2024 09:09:43 -0600 Subject: [PATCH 3/6] Create ExoConnector Check Doc --- .../HealthChecker/ExoConnectorCheck.md | 30 +++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 31 insertions(+) create mode 100644 docs/Diagnostics/HealthChecker/ExoConnectorCheck.md diff --git a/docs/Diagnostics/HealthChecker/ExoConnectorCheck.md b/docs/Diagnostics/HealthChecker/ExoConnectorCheck.md new file mode 100644 index 0000000000..5b39bf599f --- /dev/null +++ b/docs/Diagnostics/HealthChecker/ExoConnectorCheck.md @@ -0,0 +1,30 @@ +# Exchange Online Connector Check + +This is a simple check that can be performed from the Exchange On Prem side to quickly determine if the EXO connector is misconfigured. This does not completely determine if the connector is misconfigured, as Health Checker script is not designed to connect to Exchange Online to properly determine if everything is correctly configured for the way you want your mail flow to work. + +A Send Connector is determined to be destined for Exchange Online if one of the following is true: + +- SmartHost endpoint has a `*.mail.protection.outlook.com` +- AddressSpaces address has a `*.mail.onmicrosoft.com` + +For those connectors, we then determine a misconfiguration if one of the following is true: + +- TLSCertificateName is not set +- CloudServicesMailEnabled is not set to true + +These are now being flagged as an issue due to some recent changes within Exchange Online. + +Some additional configuration concerns are also warned about if one of the following is true: + +- TLSAuthLevel is not set to `DomainValidation` +- TLSDomain is not set to `mail.protection.outlook.com` + +## Included in HTML Report? + +Yes + +## Additional resources + +[Set up connectors to route mail between Microsoft 365 or Office 365 and your own email servers](https://learn.microsoft.com/exchange/mail-flow-best-practices/use-connectors-to-configure-mail-flow/set-up-connectors-to-route-mail) + +[Updated Requirements for SMTP Relay through Exchange Online](https://techcommunity.microsoft.com/t5/exchange-team-blog/updated-requirements-for-smtp-relay-through-exchange-online/ba-p/3851357) diff --git a/mkdocs.yml b/mkdocs.yml index e4340212cc..5c19b2d221 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -29,6 +29,7 @@ nav: - FindFrontEndActivity: Diagnostics/FindFrontEndActivity/FindFrontEndActivity.md - HealthChecker: - Diagnostics/HealthChecker/index.md + - ExoConnectorCheck: Diagnostics/HealthChecker/ExoConnectorCheck.md - MaintenanceCheck: Diagnostics/HealthChecker/ExchangeServerMaintenanceCheck.md - GCModeCheck: Diagnostics/HealthChecker/MAPIFrontEndAppPoolGCModeCheck.md - RebootPending: Diagnostics/HealthChecker/RebootPending.md From 045b0e53908eaa8afa452592eb914afd334c291c Mon Sep 17 00:00:00 2001 From: David Paulson Date: Fri, 9 Feb 2024 12:27:46 -0600 Subject: [PATCH 4/6] Update pester for the new logic with EXO Connector --- .../HealthChecker/Tests/HealthChecker.E15.Main.Tests.ps1 | 3 ++- .../HealthChecker/Tests/HealthChecker.E16.Main.Tests.ps1 | 3 ++- .../HealthChecker/Tests/HealthChecker.E19.Main.Tests.ps1 | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Diagnostics/HealthChecker/Tests/HealthChecker.E15.Main.Tests.ps1 b/Diagnostics/HealthChecker/Tests/HealthChecker.E15.Main.Tests.ps1 index 1b48fb42ae..05104c4d29 100644 --- a/Diagnostics/HealthChecker/Tests/HealthChecker.E15.Main.Tests.ps1 +++ b/Diagnostics/HealthChecker/Tests/HealthChecker.E15.Main.Tests.ps1 @@ -117,8 +117,9 @@ Describe "Testing Health Checker by Mock Data Imports - Exchange 2013" { TestObjectMatch "Credential Guard Enabled" $false TestObjectMatch "EdgeTransport.exe.config Present" "True" -WriteType "Green" TestObjectMatch "Open Relay Wild Card Domain" "Not Set" + TestObjectMatch "EXO Connector Present" "False" - $Script:ActiveGrouping.Count | Should -Be 10 + $Script:ActiveGrouping.Count | Should -Be 11 } It "Display Results - Security Settings" { diff --git a/Diagnostics/HealthChecker/Tests/HealthChecker.E16.Main.Tests.ps1 b/Diagnostics/HealthChecker/Tests/HealthChecker.E16.Main.Tests.ps1 index 1d86ac423a..b0ffcde76e 100644 --- a/Diagnostics/HealthChecker/Tests/HealthChecker.E16.Main.Tests.ps1 +++ b/Diagnostics/HealthChecker/Tests/HealthChecker.E16.Main.Tests.ps1 @@ -117,8 +117,9 @@ Describe "Testing Health Checker by Mock Data Imports - Exchange 2016" { TestObjectMatch "Credential Guard Enabled" $false TestObjectMatch "EdgeTransport.exe.config Present" "True" -WriteType "Green" TestObjectMatch "Open Relay Wild Card Domain" "Not Set" + TestObjectMatch "EXO Connector Present" "False" - $Script:ActiveGrouping.Count | Should -Be 10 + $Script:ActiveGrouping.Count | Should -Be 11 } It "Display Results - Security Settings" { diff --git a/Diagnostics/HealthChecker/Tests/HealthChecker.E19.Main.Tests.ps1 b/Diagnostics/HealthChecker/Tests/HealthChecker.E19.Main.Tests.ps1 index 319c1ad83d..4497cba3b8 100644 --- a/Diagnostics/HealthChecker/Tests/HealthChecker.E19.Main.Tests.ps1 +++ b/Diagnostics/HealthChecker/Tests/HealthChecker.E19.Main.Tests.ps1 @@ -119,8 +119,9 @@ Describe "Testing Health Checker by Mock Data Imports" { TestObjectMatch "EdgeTransport.exe.config Present" "True" -WriteType "Green" TestObjectMatch "NodeRunner.exe memory limit" "0 MB" -WriteType "Green" TestObjectMatch "Open Relay Wild Card Domain" "Not Set" + TestObjectMatch "EXO Connector Present" "True" # Custom EXO Connector with no TlsDomain TlsAuthLevel - $Script:ActiveGrouping.Count | Should -Be 10 + $Script:ActiveGrouping.Count | Should -Be 14 } It "Display Results - Security Settings" { From c56b281996d7e228c9b8589f6047ef63e6507e9c Mon Sep 17 00:00:00 2001 From: David Paulson Date: Fri, 9 Feb 2024 12:51:24 -0600 Subject: [PATCH 5/6] TlsAuthLevel need to be CertificateValidation or DomainValidation --- .../Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 | 5 +++-- docs/Diagnostics/HealthChecker/ExoConnectorCheck.md | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 b/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 index d75bb69b41..aa7e6e6a70 100644 --- a/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 +++ b/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 @@ -300,10 +300,11 @@ function Invoke-AnalyzerFrequentConfigurationIssues { $showMoreInfo = $true } - if ($connector.TlsAuthLevel -ne "DomainValidation") { + if ($connector.TlsAuthLevel -ne "DomainValidation" -and + $connector.TlsAuthLevel -ne "CertificateValidation") { $params = $baseParams + @{ Name = "Send Connector - $($connector.Identity.ToString())" - Details = "TlsAuthLevel not set to DomainValidation" + Details = "TlsAuthLevel not set to CertificateValidation or DomainValidation" DisplayCustomTabNumber = 2 DisplayWriteType = "Yellow" } diff --git a/docs/Diagnostics/HealthChecker/ExoConnectorCheck.md b/docs/Diagnostics/HealthChecker/ExoConnectorCheck.md index 5b39bf599f..0aab89e368 100644 --- a/docs/Diagnostics/HealthChecker/ExoConnectorCheck.md +++ b/docs/Diagnostics/HealthChecker/ExoConnectorCheck.md @@ -16,7 +16,7 @@ These are now being flagged as an issue due to some recent changes within Exchan Some additional configuration concerns are also warned about if one of the following is true: -- TLSAuthLevel is not set to `DomainValidation` +- TLSAuthLevel is not set to `CertificateValidation` or `DomainValidation` - TLSDomain is not set to `mail.protection.outlook.com` ## Included in HTML Report? From f62fafad94417a4d8795eb3c76e573fa741e65d9 Mon Sep 17 00:00:00 2001 From: David Paulson Date: Fri, 9 Feb 2024 13:35:28 -0600 Subject: [PATCH 6/6] Fix typo --- .../Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 b/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 index aa7e6e6a70..a3fc5bdcb5 100644 --- a/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 +++ b/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerFrequentConfigurationIssues.ps1 @@ -290,7 +290,7 @@ function Invoke-AnalyzerFrequentConfigurationIssues { $connector.CertificateDetails.TlsCertificateNameStatus -eq "TlsCertificateNameEmpty") { $params = $baseParams + @{ Name = "Send Connector - $($connector.Identity.ToString())" - Details = "Misconfigured to to send authenticated internal mail to M365." + + Details = "Misconfigured to send authenticated internal mail to M365." + "`r`n`t`t`tCloudServicesMailEnabled: $($connector.CloudEnabled)" + "`r`n`t`t`tTLSCertificateName set: $($connector.CertificateDetails.TlsCertificateNameStatus -ne "TlsCertificateNameEmpty")" DisplayCustomTabNumber = 2