From e2d9a272a5761da5dc52230f110e3ecddd8c775c Mon Sep 17 00:00:00 2001 From: David Paulson Date: Mon, 2 Oct 2023 16:04:25 -0500 Subject: [PATCH 1/4] Add Get-ExchangeVirtualDirectories --- .../Get-ExchangeInformation.ps1 | 4 + .../Get-ExchangeVirtualDirectories.ps1 | 110 ++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 diff --git a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 index b3885e2053..e9cfcc0c2d 100644 --- a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 +++ b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 @@ -15,6 +15,7 @@ . $PSScriptRoot\Get-ExchangeServerCertificates.ps1 . $PSScriptRoot\Get-ExchangeServerMaintenanceState.ps1 . $PSScriptRoot\Get-ExchangeUpdates.ps1 +. $PSScriptRoot\Get-ExchangeVirtualDirectories.ps1 . $PSScriptRoot\Get-ExSetupDetails.ps1 . $PSScriptRoot\Get-FIPFSScanEngineVersionState.ps1 . $PSScriptRoot\Get-ServerRole.ps1 @@ -63,6 +64,8 @@ function Get-ExchangeInformation { Invoke-CatchActions } + $getExchangeVirtualDirectories = Get-ExchangeVirtualDirectories -Server $Server + $registryValues = Get-ExchangeRegistryValues -MachineName $Server -CatchActionFunction ${Function:Invoke-CatchActions} $serverExchangeBinDirectory = [System.Io.Path]::Combine($registryValues.MsiInstallPath, "Bin\") Write-Verbose "Found Exchange Bin: $serverExchangeBinDirectory" @@ -161,6 +164,7 @@ function Get-ExchangeInformation { return [PSCustomObject]@{ BuildInformation = $buildInformation GetExchangeServer = $getExchangeServer + VirtualDirectories = $getExchangeVirtualDirectories GetMailboxServer = $getMailboxServer GetOwaVirtualDirectory = $getOwaVirtualDirectory GetWebServicesVirtualDirectory = $getWebServicesVirtualDirectory diff --git a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 new file mode 100644 index 0000000000..ffdebe28f1 --- /dev/null +++ b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 @@ -0,0 +1,110 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +. $PSScriptRoot\..\..\..\..\Shared\ErrorMonitorFunctions.ps1 + +function Get-ExchangeVirtualDirectories { + param( + [Parameter(Mandatory = $true)] + [string]$Server + ) + begin { + Write-Verbose "Calling: $($MyInvocation.MyCommand)" + + $failedString = "Failed to get {0} virtual directory." + $getActiveSyncVirtualDirectory = $null + $getAutoDiscoverVirtualDirectory = $null + $getEcpVirtualDirectory = $null + $getMapiVirtualDirectory = $null + $getOabVirtualDirectory = $null + $getOutlookAnywhere = $null + $getOwaVirtualDirectory = $null + $getPowerShellVirtualDirectory = $null + $getWebServicesVirtualDirectory = $null + $paramsNoShow = @{ + Server = $Server + ErrorAction = "Stop" + } + $params = $paramsNoShow + @{ + ShowMailboxVirtualDirectories = $true + } + } + process { + try { + $getActiveSyncVirtualDirectory = Get-ActiveSyncVirtualDirectory @params + } catch { + Write-Verbose ($failedString -f "EAS") + Invoke-CatchActions + } + + try { + $getAutoDiscoverVirtualDirectory = Get-AutodiscoverVirtualDirectory @params + } catch { + Write-Verbose ($failedString -f "Autodiscover") + Invoke-CatchActions + } + + try { + $getEcpVirtualDirectory = Get-EcpVirtualDirectory @params + } catch { + Write-Verbose ($failedString -f "ECP") + Invoke-CatchActions + } + + try { + # Doesn't have ShowMailboxVirtualDirectories + $getMapiVirtualDirectory = Get-MapiVirtualDirectory @paramsNoShow + } catch { + Write-Verbose ($failedString -f "Mapi") + Invoke-CatchActions + } + + try { + $getOabVirtualDirectory = Get-OabVirtualDirectory @params + } catch { + Write-Verbose ($failedString -f "OAB") + Invoke-CatchActions + } + + try { + $getOutlookAnywhere = Get-OutlookAnywhere @params + } catch { + Write-Verbose ($failedString -f "Outlook Anywhere") + Invoke-CatchActions + } + + try { + $getOwaVirtualDirectory = Get-OwaVirtualDirectory @params + } catch { + Write-Verbose ($failedString -f "OWA") + Invoke-CatchActions + } + + try { + $getPowerShellVirtualDirectory = Get-PowerShellVirtualDirectory @params + } catch { + Write-Verbose ($failedString -f "PowerShell") + Invoke-CatchActions + } + + try { + $getWebServicesVirtualDirectory = Get-WebServicesVirtualDirectory @params + } catch { + Write-Verbose ($failedString -f "EWS") + Invoke-CatchActions + } + } + end { + return [PSCustomObject]@{ + GetActiveSyncVirtualDirectory = $getActiveSyncVirtualDirectory + GetAutoDiscoverVirtualDirectory = $getAutoDiscoverVirtualDirectory + GetEcpVirtualDirectory = $getEcpVirtualDirectory + GetMapiVirtualDirectory = $getMapiVirtualDirectory + GetOabVirtualDirectory = $getOabVirtualDirectory + GetOutlookAnywhere = $getOutlookAnywhere + GetOwaVirtualDirectory = $getOwaVirtualDirectory + GetPowerShellVirtualDirectory = $getPowerShellVirtualDirectory + GetWebServicesVirtualDirectory = $getWebServicesVirtualDirectory + } + } +} From de2157cc24fb79d3f109c04b9c19f9c4d6d6fa50 Mon Sep 17 00:00:00 2001 From: David Paulson Date: Mon, 2 Oct 2023 17:47:53 -0500 Subject: [PATCH 2/4] Use the new location for virtual directories --- .../Analyzer/Invoke-AnalyzerExchangeInformation.ps1 | 10 ++++++---- .../Security/Invoke-AnalyzerSecurityCve-2021-1730.ps1 | 3 ++- .../ExchangeInformation/Get-ExchangeInformation.ps1 | 10 ---------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerExchangeInformation.ps1 b/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerExchangeInformation.ps1 index 5857857f54..ccbad70674 100644 --- a/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerExchangeInformation.ps1 +++ b/Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerExchangeInformation.ps1 @@ -21,6 +21,8 @@ function Invoke-AnalyzerExchangeInformation { $keyExchangeInformation = Get-DisplayResultsGroupingKey -Name "Exchange Information" -DisplayOrder $Order $exchangeInformation = $HealthServerObject.ExchangeInformation $hardwareInformation = $HealthServerObject.HardwareInformation + $getWebServicesVirtualDirectory = $exchangeInformation.VirtualDirectories.GetWebServicesVirtualDirectory | + Where-Object { $_.Name -eq "EWS (Default Web Site)" } $baseParams = @{ AnalyzedInformation = $AnalyzeResults @@ -208,8 +210,8 @@ function Invoke-AnalyzerExchangeInformation { if ($exchangeInformation.GetExchangeServer.IsEdgeServer -eq $false) { Write-Verbose "Working on MRS Proxy Settings" - $mrsProxyDetails = $exchangeInformation.GetWebServicesVirtualDirectory.MRSProxyEnabled - if ($exchangeInformation.GetWebServicesVirtualDirectory.MRSProxyEnabled) { + $mrsProxyDetails = $getWebServicesVirtualDirectory.MRSProxyEnabled + if ($getWebServicesVirtualDirectory.MRSProxyEnabled) { $mrsProxyDetails = "$mrsProxyDetails`n`r`t`tKeep MRS Proxy disabled if you do not plan to move mailboxes cross-forest or remote" $mrsProxyWriteType = "Yellow" } else { @@ -294,10 +296,10 @@ function Invoke-AnalyzerExchangeInformation { } Add-AnalyzedResultInformation @params - if (-not ([string]::IsNullOrWhiteSpace($exchangeInformation.GetWebServicesVirtualDirectory.InternalNLBBypassUrl))) { + if (-not ([string]::IsNullOrWhiteSpace($getWebServicesVirtualDirectory.InternalNLBBypassUrl))) { $params = $baseParams + @{ Name = "EWS Internal Bypass URL Set" - Details = "$($exchangeInformation.GetWebServicesVirtualDirectory.InternalNLBBypassUrl) - Can cause issues after KB 5001779" + Details = "$($getWebServicesVirtualDirectory.InternalNLBBypassUrl) - Can cause issues after KB 5001779" DisplayWriteType = "Red" } Add-AnalyzedResultInformation @params diff --git a/Diagnostics/HealthChecker/Analyzer/Security/Invoke-AnalyzerSecurityCve-2021-1730.ps1 b/Diagnostics/HealthChecker/Analyzer/Security/Invoke-AnalyzerSecurityCve-2021-1730.ps1 index 08c5ed11a8..5a29b178c4 100644 --- a/Diagnostics/HealthChecker/Analyzer/Security/Invoke-AnalyzerSecurityCve-2021-1730.ps1 +++ b/Diagnostics/HealthChecker/Analyzer/Security/Invoke-AnalyzerSecurityCve-2021-1730.ps1 @@ -26,7 +26,8 @@ function Invoke-AnalyzerSecurityCve-2021-1730 { $SecurityObject.IsEdgeServer -eq $false) { $downloadDomainsEnabled = $SecurityObject.OrgInformation.EnableDownloadDomains - $owaVDirObject = $SecurityObject.ExchangeInformation.GetOwaVirtualDirectory + $owaVDirObject = $SecurityObject.ExchangeInformation.VirtualDirectories.GetOwaVirtualDirectory | + Where-Object { $_.Name -eq "owa (Default Web Site)" } $displayWriteType = "Green" if (-not ($downloadDomainsEnabled)) { diff --git a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 index e9cfcc0c2d..f8e9842d7a 100644 --- a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 +++ b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 @@ -56,14 +56,6 @@ function Get-ExchangeInformation { Invoke-CatchActions } - try { - $getOwaVirtualDirectory = Get-OwaVirtualDirectory -Identity ("{0}\owa (Default Web Site)" -f $Server) -ADPropertiesOnly -ErrorAction Stop - $getWebServicesVirtualDirectory = Get-WebServicesVirtualDirectory -Server $Server -ErrorAction Stop - } catch { - Write-Verbose "Failed to get OWA or EWS virtual directory" - Invoke-CatchActions - } - $getExchangeVirtualDirectories = Get-ExchangeVirtualDirectories -Server $Server $registryValues = Get-ExchangeRegistryValues -MachineName $Server -CatchActionFunction ${Function:Invoke-CatchActions} @@ -166,8 +158,6 @@ function Get-ExchangeInformation { GetExchangeServer = $getExchangeServer VirtualDirectories = $getExchangeVirtualDirectories GetMailboxServer = $getMailboxServer - GetOwaVirtualDirectory = $getOwaVirtualDirectory - GetWebServicesVirtualDirectory = $getWebServicesVirtualDirectory ExtendedProtectionConfig = $extendedProtectionConfig ExchangeConnectors = $exchangeConnectors ExchangeServicesNotRunning = [array]$exchangeServicesNotRunning From 71aff604eb7935b988f80dfae03dfbbefc7a1b0f Mon Sep 17 00:00:00 2001 From: David Paulson Date: Wed, 4 Oct 2023 13:54:14 -0500 Subject: [PATCH 3/4] Use ADPropertiesOnly for vdir collections --- .../ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 index ffdebe28f1..0236a87567 100644 --- a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 +++ b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeVirtualDirectories.ps1 @@ -22,8 +22,9 @@ function Get-ExchangeVirtualDirectories { $getPowerShellVirtualDirectory = $null $getWebServicesVirtualDirectory = $null $paramsNoShow = @{ - Server = $Server - ErrorAction = "Stop" + Server = $Server + ErrorAction = "Stop" + ADPropertiesOnly = $true } $params = $paramsNoShow + @{ ShowMailboxVirtualDirectories = $true From 8481aff1f52ff15c2b25bb6a2cf62eb0a688ab00 Mon Sep 17 00:00:00 2001 From: David Paulson Date: Wed, 4 Oct 2023 14:18:45 -0500 Subject: [PATCH 4/4] Include Pester testing for additional cmdlets --- .../Tests/HealthChecker.MockedCalls.Tests.ps1 | 12 ++++++++++++ .../HealthCheckerTest.CommonMocks.NotPublished.ps1 | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Diagnostics/HealthChecker/Tests/HealthChecker.MockedCalls.Tests.ps1 b/Diagnostics/HealthChecker/Tests/HealthChecker.MockedCalls.Tests.ps1 index 6129e15693..bb3880fe75 100644 --- a/Diagnostics/HealthChecker/Tests/HealthChecker.MockedCalls.Tests.ps1 +++ b/Diagnostics/HealthChecker/Tests/HealthChecker.MockedCalls.Tests.ps1 @@ -41,6 +41,12 @@ Describe "Testing Health Checker by Mock Data Imports" { Mock Get-ReceiveConnector { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\GetReceiveConnector.xml" } Mock Get-SendConnector { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\GetSendConnector.xml" } Mock Get-DynamicDistributionGroup { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\GetDynamicDistributionGroupPfMailboxes.xml" } + Mock Get-ActiveSyncVirtualDirectory { return $null } + Mock Get-AutodiscoverVirtualDirectory { return $null } + Mock Get-EcpVirtualDirectory { return $null } + Mock Get-MapiVirtualDirectory { return $null } + Mock Get-OutlookAnywhere { return $null } + Mock Get-PowerShellVirtualDirectory { return $null } $Error.Clear() Get-OrganizationInformation -EdgeServer $false | Out-Null @@ -92,6 +98,12 @@ Describe "Testing Health Checker by Mock Data Imports" { Assert-MockCalled Get-ExchangeDiagnosticInfo -Exactly 1 Assert-MockCalled Get-ExchangeADSplitPermissionsEnabled -Exactly 1 Assert-MockCalled Get-DynamicDistributionGroup -Exactly 1 + Assert-MockCalled Get-ActiveSyncVirtualDirectory -Exactly 1 + Assert-MockCalled Get-AutodiscoverVirtualDirectory -Exactly 1 + Assert-MockCalled Get-EcpVirtualDirectory -Exactly 1 + Assert-MockCalled Get-MapiVirtualDirectory -Exactly 1 + Assert-MockCalled Get-OutlookAnywhere -Exactly 1 + Assert-MockCalled Get-PowerShellVirtualDirectory -Exactly 1 } } } diff --git a/Diagnostics/HealthChecker/Tests/HealthCheckerTest.CommonMocks.NotPublished.ps1 b/Diagnostics/HealthChecker/Tests/HealthCheckerTest.CommonMocks.NotPublished.ps1 index c84493ef35..0aa934ab7d 100644 --- a/Diagnostics/HealthChecker/Tests/HealthCheckerTest.CommonMocks.NotPublished.ps1 +++ b/Diagnostics/HealthChecker/Tests/HealthCheckerTest.CommonMocks.NotPublished.ps1 @@ -254,6 +254,18 @@ function Get-OrganizationConfig { function Get-DynamicDistributionGroup { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\GetDynamicDistributionGroupPfMailboxes.xml" } +# virtual directory cmdlets to return null till we do actual checks against the vDirs. +function Get-ActiveSyncVirtualDirectory { return $null } + +function Get-AutodiscoverVirtualDirectory { return $null } + +function Get-EcpVirtualDirectory { return $null } + +function Get-MapiVirtualDirectory { return $null } + +function Get-OutlookAnywhere { return $null } + +function Get-PowerShellVirtualDirectory { return $null } function Get-HybridConfiguration { return $null }