Skip to content

Commit

Permalink
Merge pull request #2282 from microsoft/FebCU15
Browse files Browse the repository at this point in the history
Exchange 2019 CU15 Release
  • Loading branch information
dpaulson45 authored Feb 10, 2025
2 parents 89f30e3 + 217b864 commit 8baad32
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 91 deletions.
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

0 comments on commit 8baad32

Please sign in to comment.