Exchange ServerHow-to

Running the Exchange Server Health Checker and fixing what it finds

Run Microsoft's Exchange Server Health Checker on every server, build the HTML report and fix the findings that come up most: missing updates, page file, TLS, KeepAlive and more.

The Exchange Server Health Checker is a free Microsoft script that compares a server against a long list of configuration problems known to cause performance issues, outages and security gaps. It should be the first thing you run before an upgrade and after every patch cycle. In this post I'll show where to get it, how to run it across all servers and build the HTML report, and how to fix the findings that come up most often.

How this guide is organised: Prerequisites → Step-by-step → Fixing the most common findings → Verify the fixes → Tips and gotchasFlow diagram of the article's sections in reading order: 1. Prerequisites. 2. Step-by-step (4 steps: Keep the script current; Check one server; Check every server and build the HTML report; Use the extra reports when you need them). 3. Fixing the most common findings. 4. Verify the fixes. 5. Tips and gotchas. Toolbox: Set-OutlookAnywhere, Advanced › Virtual memory, HealthChecker.ps1, SystemDefaultTlsVersions, SchUseStrongCrypto.1Prerequisites2Step-by-step3Fixing the mostcommon findi…4Verify the fixes5Tips andgotchas1Keep the script current2Check one server3Check every server andbuild the HTML report4Use the extra reportswhen you need themTOOLBOXSet-OutlookAnywhereAdvanced › Virtual memoryHealthChecker.ps1SystemDefaultTlsVersionsSchUseStrongCryptoHow this guide is organised: Prerequisites → Step-by-step → Fixing the most common findings → Verify the fixes → Tips and gotchasFlow diagram of the article's sections in reading order: 1. Prerequisites. 2. Step-by-step (4 steps: Keep the script current; Check one server; Check every server and build the HTML report; Use the extra reports when you need them). 3. Fixing the most common findings. 4. Verify the fixes. 5. Tips and gotchas. Toolbox: Set-OutlookAnywhere, Advanced › Virtual memory, HealthChecker.ps1, SystemDefaultTlsVersions, SchUseStrongCrypto.1Prerequisites2Step-by-step1Keep the script current2Check one server3Check every server and build the HTML report4Use the extra reports when you need them3Fixing the most common findings4Verify the fixes5Tips and gotchasTOOLBOXSet-OutlookAnywhereAdvanced › Virtual memoryHealthChecker.ps1SystemDefaultTlsVersionsSchUseStrongCrypto
At a glance: how this guide is organised · 4 steps · 5 key settings and tools

Prerequisites#

  • Supported versions: Exchange Server 2016, 2019 and Subscription Edition (SE).
  • Permissions: local Administrator on the servers and membership of Organization Management. Domain Admins is needed only for the -DCCoreRatio check.
  • Where to run it: an elevated Exchange Management Shell on an Exchange server.
  • The script: download HealthChecker.ps1 from the "Download the latest release" link on the Health Checker page of Microsoft's CSS-Exchange project. Avoid copies from blogs or old file shares.

Step-by-step: run the checks and build the report#

1. Keep the script current#

Health Checker looks for a newer version each time it runs. For servers without internet access, refresh it on a machine that has access (the update switch doesn't need EMS or elevation) and copy it across:

PowerShell
.\HealthChecker.ps1 -ScriptUpdateOnly

The security checks are only as current as the script, so an old copy can report "all good" on a server that is missing recent fixes.

2. Check one server#

PowerShell
.\HealthChecker.ps1                 # local server
.\HealthChecker.ps1 -Server EX01    # a specific server

Results appear on screen, colour-coded (red for errors, yellow for warnings), and are saved as a log and an XML data file in the current folder, or in the folder you pass to -OutputFilePath.

3. Check every server and build the HTML report#

PowerShell
Get-ExchangeServer | Where-Object { $_.AdminDisplayVersion -Match "^Version 15" } | .\HealthChecker.ps1
.\HealthChecker.ps1 -BuildHtmlServersReport -HtmlReportFile "ExchangeAllServersReport.html"
.\ExchangeAllServersReport.html

The HTML report puts all servers side by side, which makes configuration drift easy to spot. If the XML files are elsewhere, add -XMLDirectoryPath. With -AnalyzeDataOnly you can analyse XML files that were collected earlier.

4. Use the extra reports when you need them#

  • -VulnerabilityReport collects vulnerability information for all servers and exports it to JSON, which is handy for security teams.
  • -MailboxReport -Server EX01 produces a mailbox report for a single server.
  • -LoadBalancingReport -SiteName SiteA shows how client connections are spread across servers.
  • -DCCoreRatio compares Exchange and domain controller cores in the current site.

Fixing the most common findings#

FindingWhy it mattersFix
Build out of date, or vulnerabilities listed in the Security Vulnerability sectionThe server is missing published security fixesInstall the latest Security Update for your CU (see my security update guide)
Pending rebootUpdates and Setup can fail or behave unpredictablyRestart in a maintenance window, then re-run the check
Power plan isn't High performanceCPU throttling adds latencySet the High performance plan (below) and check the BIOS power profile
Page file managed by the system, the wrong size, or more than one page fileA known cause of performance problems on Exchange serversOne static page file, minimum = maximum: 25% of RAM on 2019 and SE; RAM + 10 MB (capped at 32,778 MB) on 2016
TCP KeepAliveTime not setWindows then waits two hours, and firewalls or load balancers may drop idle sessions firstSet 30 minutes (1800000 ms)
TLS settings inconsistentFailed connections; Extended Protection depends on consistent TLSMatch the Client and Server values for each protocol, and set SystemDefaultTlsVersions and SchUseStrongCrypto to 1 for .NET 4 (64-bit and Wow6432Node keys)
Extended Protection not configured, or SSL offloading on Outlook AnywhereLeaves the server open to authentication relay attacksFix TLS first, set -SSLOffloading $false with Set-OutlookAnywhere, then run Microsoft's ExchangeExtendedProtectionManagement.ps1
Download Domains not configuredOWA attachments are served from the main OWA host nameConfigure a separate download host name (below)
SMB1 installed or Credential Guard enabledSMB1 is an unnecessary legacy protocol; Credential Guard isn't supported on ExchangeRemove SMB1 and turn off Credential Guard

Host settings: power plan, KeepAlive and page file#

PowerShell
powercfg /setactive SCHEME_MIN
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" `
  -Name KeepAliveTime -PropertyType DWord -Value 1800000 -Force
# Page file for a 2019/SE server with 128 GB RAM (25% = 32768 MB)
wmic ComputerSystem set AutomaticManagedPagefile=False
wmic PageFileSet set InitialSize=32768,MaximumSize=32768

SCHEME_MIN is the built-in alias for High performance. If WMIC isn't available, set the page file under System Properties › Advanced › Performance Settings › Advanced › Virtual memory. The KeepAlive and page file changes need a restart.

Download Domains#

PowerShell
Get-OwaVirtualDirectory | Set-OwaVirtualDirectory -ExternalDownloadHostName download.contoso.com `
  -InternalDownloadHostName download.contoso.com
Set-OrganizationConfig -EnableDownloadDomains $true

Create the DNS record first and make sure the host name is on your Exchange certificate, or OWA attachments will stop opening.

Verify the fixes#

Re-run the script on every server and rebuild the HTML report. Good looks like:

  • No red entries, and every remaining yellow warning is understood and documented.
  • The Security Vulnerability section reports no known issues and the build shows the latest Security Update.
  • Power plan, page file, KeepAlive and TLS values are identical across servers in the HTML report.
  • Extended Protection is shown as configured, and OWA, Outlook and mobile clients still connect.

Tips and gotchas#

  • Run it after every update cycle, not just once. Updates, new servers and well-meant manual changes all cause drift.
  • Batch the restarts. Many host fixes need a reboot, so group them and use DAG maintenance mode as described in my in-place upgrade walkthrough.
  • Order matters for Extended Protection. Enabling it with inconsistent TLS or SSL offloading still in place breaks client connections.
  • Keep the XML files. They give you a before-and-after record for change management and audits.
  • Before upgrading to SE, clear the red findings first; see the SE planning guide.

References#

Written and checked against current Microsoft Learn documentation. Test changes with a pilot group before rolling them out to everyone, and if an admin center path has moved since, search for the setting name instead.

Spotted a mistake, or did this fix work differently for you? Email me or message me on LinkedIn — corrections are credited in the article.

Written by

Omer Eltayeb

Intune Subject Matter Expert in Cairo, Egypt, former Microsoft Cloud Solutions Architect, Microsoft Certified Trainer and Microsoft Innovative Educator Expert (2024–26) and Microsoft Elevate Educator Expert (2026–27). I share practical, step-by-step guides, study plans, scripts and toolkits for Microsoft Intune, Configuration Manager, Microsoft Entra ID, Microsoft Defender, Exchange and Microsoft 365 with the community.

Microsoft Certified Trainer (MCT) 2026Microsoft Innovative Educator Expert 2025–2026Microsoft Elevate Educator Expert 2026–2027ISC2 Certified Information Systems Security Professional (CISSP)Microsoft 365 Certified: Enterprise Administrator Expert (MS-102)