Skip to content

Commit

Permalink
Merge pull request #1975 from microsoft/main
Browse files Browse the repository at this point in the history
Release 2-7-24
  • Loading branch information
dpaulson45 authored Feb 7, 2024
2 parents c6212ff + dbfbb0f commit b1511fc
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@ function Invoke-AnalyzerExchangeInformation {
}
}

# If the ExSetup wasn't found, we need to report that.
if ($exchangeInformation.BuildInformation.ExchangeSetup.FailedGetExSetup -eq $true) {
$params = $baseParams + @{
Name = "Warning"
Details = "Didn't detect ExSetup.exe on the server. This might mean that setup didn't complete correctly the last time it was run."
DisplayCustomTabNumber = 2
DisplayWriteType = "Yellow"
}
Add-AnalyzedResultInformation @params
}

if ($null -ne $exchangeInformation.BuildInformation.KBsInstalled) {
Add-AnalyzedResultInformation -Name "Exchange IU or Security Hotfix Detected" @baseParams
$problemKbFound = $false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
foreach ($configKey in $keyList) {

$configStatus = $exchangeInformation.ApplicationConfigFileStatus[$configKey]
$fileName = $configStatus.FileName
$writeType = "Green"
[string]$writeValue = $configStatus.Present

Expand All @@ -155,12 +156,12 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
}

$params = $baseParams + @{
Name = "$configKey Present"
Name = "$fileName Present"
Details = $writeValue
DisplayWriteType = $writeType
}

if ($alwaysDisplayConfigs -contains $configKey -or
if ($alwaysDisplayConfigs -contains $fileName -or
-not $configStatus.Present) {
Add-AnalyzedResultInformation @params
}
Expand All @@ -171,7 +172,7 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
$content = [xml]($configStatus.Content)

# Additional checks of configuration files.
if ($configKey -eq "noderunner.exe.config") {
if ($fileName -eq "noderunner.exe.config") {
$memoryLimitMegabytes = $content.configuration.nodeRunnerSettings.memoryLimitMegabytes
$writeValue = "$memoryLimitMegabytes MB"
$writeType = "Green"
Expand Down Expand Up @@ -205,7 +206,7 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
}
} catch {
$params = $baseParams + @{
Name = "$configKey Invalid Config Format"
Name = "$fileName Invalid Config Format"
Details = "True --- Error: Not able to convert to xml which means it is in an incorrect format that will cause problems with the process."
DisplayTestingValue = $true
DisplayWriteType = "Red"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,6 @@ function Invoke-AnalyzerIISInformation {
$problemCertList.Add("'$certHash' Doesn't exist on the server and this will cause problems.")
} elseif ($cert.LifetimeInDays -lt 0) {
$problemCertList.Add("'$certHash' Has expired and will cause problems.")
} elseif ($_.bindingInformation -eq "*:444:") {
$namespaces = $cert.Namespaces | ForEach-Object { $_.ToString() }

if ($namespaces -notcontains $exchangeInformation.GetExchangeServer.Fqdn -or
$namespaces -notcontains $exchangeInformation.GetExchangeServer.Name) {
$problemCertList.Add("'$certHash' Exchange Back End does not have hostname or FQDN for the namespaces. This can cause connectivity issues.")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@ function Invoke-AnalyzerSecurityExtendedProtectionConfigState {
# This combination means that EP is not configured and the Exchange build doesn't support it.
# Recommended action: Upgrade to a supported build (Aug 2022 SU+) and enable EP afterwards.
$epDetails = "Your Exchange server is at risk. Install the latest SU and enable Extended Protection"
} else {
} elseif ($extendedProtection.ExtendedProtectionConfigured) {
# This means that EP is supported but not configured for at least one vDir.
# Recommended action: Enable EP for each vDir on the system by using the script provided by us.
$epDetails += "Extended Protection isn't configured as expected"
$epDetails = "Extended Protection isn't configured as expected"
} else {
# No Extended Protection is configured, provide a slightly different wording to avoid confusion of possible misconfigured EP.
$epDetails = "Extended Protection is not configured"
}

$epCveParams = $baseParams + @{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,20 @@ function Get-ExSetupDetails {
Write-Verbose "Calling: $($MyInvocation.MyCommand)"
$exSetupDetails = [string]::Empty
function Get-ExSetupDetailsScriptBlock {
Get-Command ExSetup | ForEach-Object { $_.FileVersionInfo }
try {
Get-Command ExSetup -ErrorAction Stop | ForEach-Object { $_.FileVersionInfo }
} catch {
try {
Write-Verbose "Failed to find ExSetup by environment path locations. Attempting manual lookup."
$installDirectory = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\ExchangeServer\v15\Setup -ErrorAction Stop).MsiInstallPath

if ($null -ne $installDirectory) {
Get-Command ([System.IO.Path]::Combine($installDirectory, "bin\ExSetup.exe")) -ErrorAction Stop | ForEach-Object { $_.FileVersionInfo }
}
} catch {
Write-Verbose "Failed to find ExSetup, need to fallback."
}
}
}

$exSetupDetails = Invoke-ScriptBlockHandler -ComputerName $Server -ScriptBlock ${Function:Get-ExSetupDetailsScriptBlock} -ScriptBlockDescription "Getting ExSetup remotely" -CatchActionFunction ${Function:Invoke-CatchActions}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
. $PSScriptRoot\..\..\..\..\Shared\ErrorMonitorFunctions.ps1
. $PSScriptRoot\..\..\..\..\Shared\Get-ExchangeBuildVersionInformation.ps1
. $PSScriptRoot\..\..\..\..\Shared\Get-ExchangeSettingOverride.ps1
. $PSScriptRoot\..\..\..\..\Shared\Get-FileContentInformation.ps1
. $PSScriptRoot\IISInformation\Get-ExchangeAppPoolsInformation.ps1
. $PSScriptRoot\IISInformation\Get-ExchangeServerIISSettings.ps1
. $PSScriptRoot\Get-ExchangeAES256CBCDetails.ps1
. $PSScriptRoot\Get-ExchangeApplicationConfigurationFileValidation.ps1
. $PSScriptRoot\Get-ExchangeConnectors.ps1
. $PSScriptRoot\Get-ExchangeDependentServices.ps1
. $PSScriptRoot\Get-ExchangeRegistryValues.ps1
Expand Down Expand Up @@ -36,7 +36,21 @@ function Get-ExchangeInformation {
$getExchangeServer = (Get-ExchangeServer -Identity $Server -Status)
$exchangeCertificates = Get-ExchangeServerCertificates -Server $Server
$exSetupDetails = Get-ExSetupDetails -Server $Server
$versionInformation = (Get-ExchangeBuildVersionInformation -FileVersion ($exSetupDetails.FileVersion))

if ($null -eq $exSetupDetails) {
# couldn't find ExSetup.exe this should be rare so we are just going to handle this by displaying the AdminDisplayVersion from Get-ExchangeServer
$versionInformation = (Get-ExchangeBuildVersionInformation -AdminDisplayVersion $getExchangeServer.AdminDisplayVersion)
$exSetupDetails = [PSCustomObject]@{
FileVersion = $versionInformation.BuildVersion.ToString()
FileBuildPart = $versionInformation.BuildVersion.Build
FilePrivatePart = $versionInformation.BuildVersion.Revision
FileMajorPart = $versionInformation.BuildVersion.Major
FileMinorPart = $versionInformation.BuildVersion.Minor
FailedGetExSetup = $true
}
} else {
$versionInformation = (Get-ExchangeBuildVersionInformation -FileVersion ($exSetupDetails.FileVersion))
}

$buildInformation = [PSCustomObject]@{
ServerRole = (Get-ServerRole -ExchangeServerObj $getExchangeServer)
Expand Down Expand Up @@ -98,12 +112,12 @@ function Get-ExchangeInformation {
}

$configParams = @{
ComputerName = $Server
ConfigFileLocation = @("$([System.IO.Path]::Combine($serverExchangeBinDirectory, "EdgeTransport.exe.config"))",
ComputerName = $Server
FileLocation = @("$([System.IO.Path]::Combine($serverExchangeBinDirectory, "EdgeTransport.exe.config"))",
"$([System.IO.Path]::Combine($serverExchangeBinDirectory, "Search\Ceres\Runtime\1.0\noderunner.exe.config"))")
}

$applicationConfigFileStatus = Get-ExchangeApplicationConfigurationFileValidation @configParams
$applicationConfigFileStatus = Get-FileContentInformation @configParams
$serverMaintenance = Get-ExchangeServerMaintenanceState -Server $Server -ComponentsToSkip "ForwardSyncDaemon", "ProvisioningRps"
$settingOverrides = Get-ExchangeSettingOverride -Server $Server -CatchActionFunction ${Function:Invoke-CatchActions}

Expand Down
28 changes: 18 additions & 10 deletions Diagnostics/HealthChecker/Features/Get-HealthCheckerData.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,27 @@ function Get-HealthCheckerData {
Write-Progress @paramWriteProgress

try {
$analyzedResults | Export-Clixml -Path $Script:OutXmlFullPath -Encoding UTF8 -Depth 2 -ErrorAction SilentlyContinue
$analyzedResults | Export-Clixml -Path $Script:OutXmlFullPath -Encoding UTF8 -Depth 2 -ErrorAction Stop
Write-Verbose "Successfully export out the data"
} catch {
Write-Verbose "Failed to Export-Clixml. Converting HealthCheckerExchangeServer to json"
$jsonHealthChecker = $analyzedResults.HealthCheckerExchangeServer | ConvertTo-Json

$testOutputXml = [PSCustomObject]@{
HealthCheckerExchangeServer = $jsonHealthChecker | ConvertFrom-Json
HtmlServerValues = $analyzedResults.HtmlServerValues
DisplayResults = $analyzedResults.DisplayResults
try {
Write-Verbose "Failed to Export-Clixml. Inner Exception: $_"
Write-Verbose "Converting HealthCheckerExchangeServer to json."
$jsonHealthChecker = $analyzedResults.HealthCheckerExchangeServer | ConvertTo-Json -Depth 6 -ErrorAction Stop

$testOutputXml = [PSCustomObject]@{
HealthCheckerExchangeServer = $jsonHealthChecker | ConvertFrom-Json -ErrorAction Stop
HtmlServerValues = $analyzedResults.HtmlServerValues
DisplayResults = $analyzedResults.DisplayResults
}

$testOutputXml | Export-Clixml -Path $Script:OutXmlFullPath -Encoding UTF8 -Depth 2 -ErrorAction Stop
Write-Verbose "Successfully export out the data after the convert"
} catch {
Write-Red "Failed to Export-Clixml. Unable to export the data."
}

$testOutputXml | Export-Clixml -Path $Script:OutXmlFullPath -Encoding UTF8 -Depth 2 -ErrorAction Stop
} finally {
# This prevents the need to call Invoke-CatchActions
Invoke-ErrorCatchActionLoopFromIndex $currentErrors

# for now don't want to display that we output the information if ReturnDataCollectionOnly is false
Expand Down
2 changes: 2 additions & 0 deletions Diagnostics/HealthChecker/Features/Get-HtmlServerReport.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,6 @@ function Get-HtmlServerReport {
$htmlReport = $htmlHeader + $htmlOverviewTable + $htmlServerDetails + "</body>$([System.Environment]::NewLine)</html>"

$htmlReport | Out-File $HtmlOutFilePath -Encoding UTF8

Write-Host "HTML Report Location: $HtmlOutFilePath"
}
2 changes: 1 addition & 1 deletion Diagnostics/HealthChecker/HealthChecker.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ param(
[switch]$BuildHtmlServersReport,

[Parameter(Mandatory = $false, ParameterSetName = "HTMLReport", HelpMessage = "Provide the name of the Report to be created.")]
[string]$HtmlReportFile = "ExchangeAllServersReport.html",
[string]$HtmlReportFile = "ExchangeAllServersReport-$((Get-Date).ToString("yyyyMMddHHmmss")).html",

[Parameter(Mandatory = $true, ParameterSetName = "DCCoreReport", HelpMessage = "Enable the DCCoreReport feature data collection against the current server's AD Site.")]
[switch]$DCCoreRatio,
Expand Down
46 changes: 46 additions & 0 deletions Shared/Get-FileContentInformation.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\Invoke-ScriptBlockHandler.ps1
function Get-FileContentInformation {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$ComputerName,

[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string[]]$FileLocation
)
begin {
Write-Verbose "Calling: $($MyInvocation.MyCommand)"
$allFiles = New-Object System.Collections.Generic.List[string]
}
process {
foreach ($file in $FileLocation) {
$allFiles.Add($file)
}
}
end {
$params = @{
ComputerName = $ComputerName
ScriptBlockDescription = "Getting File Content Information"
ArgumentList = @(, $allFiles)
ScriptBlock = {
param($FileLocations)
$results = @{}
foreach ($fileLocation in $FileLocations) {
$obj = [PSCustomObject]@{
Present = ((Test-Path $fileLocation))
FileName = ([IO.Path]::GetFileName($fileLocation))
FilePath = $fileLocation
Content = (Get-Content $fileLocation -Raw)
}

$results.Add($fileLocation, $obj)
}
return $results
}
}
return (Invoke-ScriptBlockHandler @params)
}
}
2 changes: 1 addition & 1 deletion docs/Diagnostics/HealthChecker/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ ServerList | Used in combination with the LoadBalancingReport switch for letting
SiteName | Used in combination with the LoadBalancingReport switch for letting the script to know which servers to run against in the site.
XMLDirectoryPath | Used in combination with BuildHtmlServersReport switch for the location of the HealthChecker XML files for servers which you want to be included in the report. Default location is the current directory.
BuildHtmlServersReport | Switch to enable the script to build the HTML report for all the servers XML results in the XMLDirectoryPath location.
HtmlReportFile | Name of the HTML output file from the BuildHtmlServersReport. Default is ExchangeAllServersReport.html
HtmlReportFile | Name of the HTML output file from the BuildHtmlServersReport. Default is ExchangeAllServersReport-yyyyMMddHHmmss.html
DCCoreRatio | Gathers the Exchange to DC/GC Core ratio and displays the results in the current site that the script is running in.
AnalyzeDataOnly | Switch to analyze the existing HealthChecker XML files. The results are displayed on the screen and an HTML report is generated.
VulnerabilityReport | Switch to collect the Vulnerability Information for all the servers in the environment and export it out to json file.
Expand Down

0 comments on commit b1511fc

Please sign in to comment.