Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
. $PSScriptRoot\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\Get-DisplayResultsGroupingKey.ps1
. $PSScriptRoot\Invoke-AnalyzerKnownBuildIssues.ps1
. $PSScriptRoot\..\..\..\Shared\CompareExchangeBuildLevel.ps1
function Invoke-AnalyzerExchangeInformation {
[CmdletBinding()]
param(
Expand Down Expand Up @@ -581,6 +582,89 @@ function Invoke-AnalyzerExchangeInformation {
}
}

if ((Test-ExchangeBuildGreaterOrEqualThanBuild -CurrentExchangeBuild $exchangeInformation.BuildInformation.VersionInformation -Version "Exchange2019" -CU "CU15") -and
$exchangeInformation.GetExchangeServer.IsEdgeServer -eq $false) {
# This feature only needs to be displayed if we are on Exchange 2019 CU15+
if ($null -eq $exchangeInformation.GetExchangeServer.RingLevel) {
$params = $baseParams + @{
Name = "Feature Flighting"
Details = "Unknown - No data on Get-ExchangeServer related to this feature. Likely due to connecting to an Exchange Server for shell not on supported build."
DisplayWriteType = "Yellow"
}
Add-AnalyzedResultInformation @params
} else {
Add-AnalyzedResultInformation @baseParams -Name "Feature Flighting"

$getExchangeServer = $exchangeInformation.GetExchangeServer
$flightingBaseParams = $baseParams + @{ DisplayCustomTabNumber = 2 }
$params = $flightingBaseParams + @{
Name = "Ring Level"
Details = $getExchangeServer.RingLevel
}
Add-AnalyzedResultInformation @params

$endpointDisplayWriteType = "Grey"
$endpointDetails = "200 - Reachable"
if ($exchangeInformation.ExchangeFeatureFlightingServiceResult.StatusCode -ne 200) {
$endpointDisplayWriteType = "Yellow"
$endpointDetails = "Unreachable - More Information: https://aka.ms/HC-ExchangeServerFeatureFlighting"
}
$params = $flightingBaseParams + @{
Name = "Endpoint Service Status"
Details = $endpointDetails
DisplayWriteType = $endpointDisplayWriteType
}
Add-AnalyzedResultInformation @params

$params = $flightingBaseParams + @{
Name = "Last Service Run Time"
Details = $getExchangeServer.LastFlightingServiceRunTime
}
Add-AnalyzedResultInformation @params

if ($getExchangeServer.FeaturesEnabled.Count -gt 0) {
$details = ([string]::Join(", ", $getExchangeServer.FeaturesEnabled))
} else {
$details = "None Enabled"
}
$params = $flightingBaseParams + @{
Name = "Features Enabled"
Details = $details
}
Add-AnalyzedResultInformation @params

# The rest of the settings, only display if we have something there.
if ($getExchangeServer.FeaturesApproved.Count -gt 0) {
$params = $flightingBaseParams + @{
Name = "Features Approved"
Details = ([string]::Join(", ", $getExchangeServer.FeaturesApproved))
}
Add-AnalyzedResultInformation @params
}
if ($getExchangeServer.FeaturesAwaitingAdminApproval.Count -gt 0) {
$params = $flightingBaseParams + @{
Name = "Features Awaiting Admin Approval"
Details = ([string]::Join(", ", $getExchangeServer.FeaturesAwaitingAdminApproval))
}
Add-AnalyzedResultInformation @params
}
if ($getExchangeServer.FeaturesBlocked.Count -gt 0) {
$params = $flightingBaseParams + @{
Name = "Features Blocked"
Details = ([string]::Join(", ", $getExchangeServer.FeaturesBlocked))
}
Add-AnalyzedResultInformation @params
}
if ($getExchangeServer.FeaturesDisabled.Count -gt 0) {
$params = $flightingBaseParams + @{
Name = "Features Disabled"
Details = ([string]::Join(", ", $getExchangeServer.FeaturesDisabled))
}
Add-AnalyzedResultInformation @params
}
}
}

if ($null -ne $exchangeInformation.SettingOverrides) {

$overridesDetected = $null -ne $exchangeInformation.SettingOverrides.SettingOverrides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ function Invoke-AnalyzerSecurityCve-2023-36434 {

begin {
Write-Verbose "Calling: $($MyInvocation.MyCommand)"
# Because we don't have the revision number here, we don't want to provide the 4th value otherwise it will not work correctly
$notWindows2025OrGreater = $SecurityObject.OsInformation.BuildInformation.BuildVersion -lt [System.Version]"10.0.26100"
$tokenCacheModuleVersionInformation = $SecurityObject.ExchangeInformation.IISSettings.IISTokenCacheModuleInformation
$tokenCacheFixedVersionNumber = $null
$tokenCacheVersionGreaterOrEqual = $false
}
process {
if ($SecurityObject.IsEdgeServer -eq $false) {
if ($SecurityObject.IsEdgeServer -eq $false -and
$notWindows2025OrGreater) {
Write-Verbose "Testing CVE: CVE-2023-21709 / CVE-2023-36434"

if ($SecurityObject.ExchangeInformation.IISSettings.IISModulesInformation.ModuleList.Name -contains "TokenCacheModule") {
Expand Down Expand Up @@ -68,6 +71,8 @@ function Invoke-AnalyzerSecurityCve-2023-36434 {
Add-AnalyzedResultInformation @params
}
}
} elseif ( -not $notWindows2025OrGreater) {
Write-Verbose "Windows Server 2025 or greater is not affected by this vulnerability"
} else {
Write-Verbose "Edge Server Role is not affected by this vulnerability as it has no IIS installed"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\..\Get-DisplayResultsGroupingKey.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityExchangeCertificates.ps1
Expand Down Expand Up @@ -50,6 +51,7 @@ function Invoke-AnalyzerSecuritySettings {

$tlsVersions = @("1.0", "1.1", "1.2", "1.3")
$tls13SupportedOS = @("Windows2012", "Windows2012R2", "Windows2016", "Windows2019") -notcontains $osInformation.BuildInformation.MajorVersion
$tls13SupportedExchange = Test-ExchangeBuildGreaterOrEqualThanBuild -CurrentExchangeBuild $HealthServerObject.ExchangeInformation.BuildInformation.VersionInformation -Version "Exchange2019" -CU "CU15"
$currentNetVersion = $osInformation.TLSSettings.Registry.NET["NETv4"]

$tlsSettings = $osInformation.TLSSettings.Registry.TLS
Expand Down Expand Up @@ -79,12 +81,13 @@ function Invoke-AnalyzerSecuritySettings {

# Any TLS version is Misconfigured or Half Disabled is Red
# Only TLS 1.2 being Disabled is Red
# Currently TLS 1.3 being Enabled is Red
# TLS 1.3 being Enabled is Red on unsupported OS and Exchange version.
# TLS 1.3 started support with Exchange 2019 CU15 with Windows Server 2022 or newer versions
# TLS 1.0 or 1.1 being Enabled is Yellow as we recommend to disable this weak protocol versions
if (($currentTlsVersion.TLSConfiguration -eq "Misconfigured" -or
$currentTlsVersion.TLSConfiguration -eq "Half Disabled") -or
($tlsKey -eq "1.2" -and $currentTlsVersion.TLSConfiguration -eq "Disabled") -or
($tlsKey -eq "1.3" -and $currentTlsVersion.TLSConfiguration -eq "Enabled")) {
($tlsKey -eq "1.3" -and $currentTlsVersion.TLSConfiguration -eq "Enabled" -and (-not $tls13SupportedOS -or -not $tls13SupportedExchange))) {
$displayWriteType = "Red"
} elseif ($currentTlsVersion.TLSConfiguration -eq "Enabled" -and
($tlsKey -eq "1.1" -or $tlsKey -eq "1.0")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,23 +180,38 @@ function Get-ExchangeInformation {

$FIPFSUpdateIssue = Get-FIPFSScanEngineVersionState @fipFsParams

$eemsEndpointParams = @{
$endpointScriptBlock = {
param($url, $proxy)

if ($null -eq $url) {
throw "NULL URL provided for endpoint script block"
}
Write-Verbose "Going to try to get the endpoint information for: $url"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
if ($null -ne $proxy) {
Write-Verbose "Proxy Server detected. Going to use: $proxy"
[System.Net.WebRequest]::DefaultWebProxy = New-Object System.Net.WebProxy($proxy)
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
[System.Net.WebRequest]::DefaultWebProxy.BypassProxyOnLocal = $true
} elseif ($null -ne [System.Net.WebRequest]::DefaultWebProxy.Address) {
Write-Verbose "No Exchange proxy provided, but one is set on the PowerShell session. Going to remove it."
[System.Net.WebRequest]::DefaultWebProxy = $null
}
Invoke-WebRequest -Method Get -Uri $url -UseBasicParsing
}

$scriptBlockEndpointParams = @{
ComputerName = $Server
ScriptBlockDescription = "Test EEMS pattern service connectivity"
CatchActionFunction = ${Function:Invoke-CatchActions}
ArgumentList = $getExchangeServer.InternetWebProxy
ScriptBlock = {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
if ($null -ne $args[0]) {
Write-Verbose "Proxy Server detected. Going to use: $($args[0])"
[System.Net.WebRequest]::DefaultWebProxy = New-Object System.Net.WebProxy($args[0])
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
[System.Net.WebRequest]::DefaultWebProxy.BypassProxyOnLocal = $true
}
Invoke-WebRequest -Method Get -Uri "https://officeclient.microsoft.com/GetExchangeMitigations" -UseBasicParsing
}
ArgumentList = @("https://officeclient.microsoft.com/GetExchangeMitigations", $getExchangeServer.InternetWebProxy)
ScriptBlock = $endpointScriptBlock
}
$eemsEndpointResults = Invoke-ScriptBlockHandler @eemsEndpointParams
$eemsEndpointResults = Invoke-ScriptBlockHandler @scriptBlockEndpointParams

$scriptBlockEndpointParams.ScriptBlockDescription = "Test Feature Flighting service connectivity"
$scriptBlockEndpointParams.ArgumentList[0] = "https://officeclient.microsoft.com/GetExchangeConfig"
$featureFlightingEndpointResults = Invoke-ScriptBlockHandler @scriptBlockEndpointParams

Write-Verbose "Checking AES256-CBC information protection readiness and configuration"
$aes256CbcParams = @{
Expand Down Expand Up @@ -321,6 +336,7 @@ function Get-ExchangeInformation {
ServerMaintenance = $serverMaintenance
ExchangeCertificates = [array]$exchangeCertificates
ExchangeEmergencyMitigationServiceResult = $eemsEndpointResults
ExchangeFeatureFlightingServiceResult = $featureFlightingEndpointResults
EdgeTransportResourceThrottling = $edgeTransportResourceThrottling # If we want to checkout other diagnosticInfo, we should create a new object here.
ApplicationConfigFileStatus = $applicationConfigFileStatus
DependentServices = $dependentServices
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ function Get-ExchangeServerMaintenanceState {
$getServerComponentState = Get-ServerComponentState -Identity $Server -ErrorAction SilentlyContinue

try {
$errorCount = $Error.Count
$getClusterNode = Get-ClusterNode -Name $Server -ErrorAction Stop
} catch {
Write-Verbose "Failed to run Get-ClusterNode"
Invoke-CatchActions
Invoke-ErrorCatchActionLoopFromIndex $errorCount
}

Write-Verbose "Running ServerComponentStates checks"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function Get-ServerOperatingSystemVersion {
"*Server 2016*" { $osReturnValue = "Windows2016" }
"*Server 2019*" { $osReturnValue = "Windows2019" }
"*Server 2022*" { $osReturnValue = "Windows2022" }
"*Server 2025*" { $osReturnValue = "Windows2025" }
default { $osReturnValue = "Unknown" }
}
}
Expand Down
Loading