Skip to content

Exchange Server health check with PowerShell script

Incidents and problems are surfacing about Exchange Server, and you like to check the Exchange Server health. What is the best way to check the health? Perhaps you want to add a new Exchange Server to the environment, and before doing that, you want to check the health. Let’s see how to health check Exchange Server with an excellent PowerShell script.

Why you want to check Exchange Server health

It’s good to check the Exchange Server health if there are incidents, problems, or changes that you have to apply:

  • There is a problem with the Exchange Server
  • Before upgrading Exchange Server CU to the latest version
  • Before you install the hybrid configuration wizard for Office 365 migrations
  • Before you create a DAG between Exchange Servers
  • Introducing a new Exchange Server in the organization

Exchange Server health check PowerShell script

The Exchange Server Health Checker script helps detect common configuration issues known to cause performance issues and other long-running issues caused by a simple configuration change within an Exchange Environment. It also helps collect useful information about your server to help speed up common information-gathering of your server.

Why I recommend using this PowerShell script:

  • Supports Exchange Server 2013/2016/2019
  • A changelog kept with all the fixes/features
  • It’s created and maintained by Microsoft Engineers
  • Always looking for improvements
  • Open to suggestions and features
  • It’s 100% PowerShell

Good to know is that it might work on Exchange Server 2007/2010, but it’s not supported.

Download and prepare the Exchange Health check script

Download Exchange health checker PowerShell script from the official page (GitHub). At the moment of writing, I will test Exchange Server Performance Health Checker Script version 3.1.1.

The chance is big that if you read this article, the version is changed. That’s because the team releases a couple of updates every single month, which is very great! If you do have any bugs, feature suggestions, or feedback, you can email them at extoolsfeedback@microsoft.com.

Download Exchange health checker PowerShell script from GitHub

Place the HealthChecker.ps1 PowerShell script on the Exchange Server C:\scripts folder. If you don’t have a scripts folder, create one. Make sure to check if the file is unblocked to prevent any errors when running the script. Read more in the article Not digitally signed error when running PowerShell script.

Verify the signature before running the script with the Get-AuthenticodeSignature cmdlet.

[PS] C:\>Get-AuthenticodeSignature -FilePath "C:\Scripts\HealthChecker.ps1" | ft -AutoSize


    Directory: C:\Scripts


SignerCertificate                        Status Path
-----------------                        ------ ----
ABDCA79AF9DD48A0EA702AD45260B3C03093FB4B Valid  HealthChecker.ps1

Run the Exchange Server Health Checker PowerShell script

Run Exchange Management Shell as administrator on the Exchange Server. Change directory path to C:\scripts. Run HealthChecker.ps1 script and specify the Exchange Server. If you don’t identify the Exchange Server, it will check the localhost (the one you are on right now).

[PS] C:\scripts>.\HealthChecker.ps1 -Server "EX01-2016"
Exchange Health Checker version 3.1.1
Virtual Machine detected.  Certain settings about the host hardware cannot be detected from the virtual machine.  Verify on the VM Host that:

    - There is no more than a 1:1 Physical Core to Virtual CPU ratio (no oversubscribing)
    - If Hyper-Threading is enabled do NOT count Hyper-Threaded cores as physical cores
    - Do not oversubscribe memory or use dynamic memory allocation

Although Exchange technically supports up to a 2:1 physical core to vCPU ratio, a 1:1 ratio is strongly recommended for performance reasons.  Certain third party Hyper-Visors such as VMWare have their own guidance.

VMWare recommends a 1:1 ratio.  Their guidance can be found at https://www.vmware.com/files/pdf/Exchange_2013_on_VMware_Best_Practices_Guide.pdf.
Related specifically to VMWare, if you notice you are experiencing packet loss on your VMXNET3 adapter, you may want to review the following article from VMWare:  http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2039495.

For further details, please review the virtualization recommendations on Microsoft Docs at the following locations:
Exchange 2013: https://learn.microsoft.com/en-us/exchange/exchange-2013-virtualization-exchange-2013-help#requirements-for-hardware-virtualization.
Exchange 2016/2019: https://learn.microsoft.com/en-us/exchange/plan-and-deploy/virtualization?view=exchserver-2019.


Exchange Information
--------------------
        Name: EX01-2016
        Version: Exchange 2016 CU17
        Build Number: 15.1.2044.4
                Error: Out of date Cumulative Update. Please upgrade to one of the two most recently released Cumulative Updates. Currently running on a build that is 194 days old.
        Server Role: Mailbox
        MAPI/HTTP Enabled: True
        Exchange Server Maintenance: Server is not in Maintenance Mode

Operating System Information
----------------------------
        Version: Microsoft Windows Server 2016 Standard Evaluation
        System Up Time: 2 day(s) 16 hour(s) 34 minute(s) 28 second(s)
        Time Zone: W. Europe Standard Time
        Dynamic Daylight Time Enabled: True
        .NET Framework: 4.8
        Page File Size: Error: System is set to automatically manage the pagefile size.
        Power Plan: Balanced --- Error
        Http Proxy Setting: <None>
        Visual C++ 2012: Redistributable is outdated
        Visual C++ 2013: Redistributable is outdated
                Note: For more information about the latest C++ Redistributeable please visit: https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
                This is not a requirement to upgrade, only a notification to bring to your attention.
        Server Pending Reboot: False

Processor/Hardware Information
------------------------------
        Type: VMWare
        Processor: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
        Number of Processors: 4
                Note: Please make sure you are following VMware's performance recommendation to get the most out of your guest machine. VMware blog 'Does corespersocket Affect Performance?' https://blogs.vmware.com/vsphere/2013/10/does-corespersocket-affect-performance.html
        Number of Physical Cores: 4
        Number of Logical Cores: 4
        Hyper-Threading: Disabled
        All Processor Cores Visible: Passed
        Max Processor Speed: 2304
        Physical Memory: 12 GB

NIC Settings Per Active Adapter
-------------------------------
        Interface Description: vmxnet3 Ethernet Adapter [Ethernet0]
                Driver Date: 2019-07-11
                Driver Version: 1.8.16.0
                MTU Size: 1500
                RSS Enabled: True
                Link Speed: 10000 Mbps --- This may not be accurate due to virtualized hardware
                IPv6 Enabled: True
                IPv4 Address:
                        Address: 192.168.1.52\24 Gateway: 192.168.1.1
                IPv6 Address:
                DNS Server: 192.168.1.51
                Registered In DNS: True
                Sleepy NIC Disabled: False --- Warning: It's recommended to disable NIC power saving options
                        More Information: http://support.microsoft.com/kb/2740020
                Packets Received Discarded: 0

Frequent Configuration Issues
-----------------------------
        TCP/IP Settings: Not Set
                Error: Without this value the KeepAliveTime defaults to two hours, which can cause connectivity and performance issues between network devices such as firewalls and load balancers depending on their configuration.
                More details: https://techcommunity.microsoft.com/t5/Exchange-Team-Blog/Checklist-for-troubleshooting-Outlook-connectivity-in-Exchange/ba-p/604792
        RPC Min Connection Timeout: 0
                More Information: https://blogs.technet.microsoft.com/messaging_with_communications/2012/06/06/outlook-anywhere-network-timeout-issue/
        CTS Processor Affinity Percentage: 0
        Credential Guard Enabled: False

Security Settings
-----------------
        LmCompatibilityLevel Settings: 3
                Description: Clients use only NTLMv2 authentication, and they use NTLMv2 session security if the server supports it. Domain controllers accept LM, NTLM, and NTLMv2 authentication.
        TLS 1.0
                Server Enabled: True
                Server Disabled By Default: False
                Client Enabled: True
                Client Disabled By Default: False
        TLS 1.1
                Server Enabled: True
                Server Disabled By Default: False
                Client Enabled: True
                Client Disabled By Default: False
        TLS 1.2
                Server Enabled: True
                Server Disabled By Default: False
                Client Enabled: True
                Client Disabled By Default: False
        Certificate:
                FriendlyName: Microsoft Exchange Server Auth Certificate
                Thumbprint: 96AC7BAD02F000A6C9B0DFEB5F15A59FE396D5F2
                Lifetime in days: 1758
                Key size: 2048
                Bound to services: SMTP
                Current Auth Certificate: True
                SAN Certificate: False
                Namespaces:
                        Microsoft Exchange Server Auth Certificate
        Certificate:
                FriendlyName: Microsoft Exchange
                Thumbprint: 8CF11037A346A3BE602E99171FFB32C07F3F2196
                Lifetime in days: 1784
                Key size: 2048
                Bound to services: IMAP, POP, IIS, SMTP
                Current Auth Certificate: False
                SAN Certificate: True
                Namespaces:
                        EX01-2016
                        EX01-2016.exoip.local
        Certificate:
                FriendlyName: mail.exoip.com @ 2020/10/3 16:46:13
                Thumbprint: 11A8E3212103DD17734E46F5F4DFEA1ABC41AD35
                Lifetime in days: 5
                Key size: 3072
                Bound to services: IIS, SMTP
                Current Auth Certificate: False
                SAN Certificate: True
                Namespaces:
                        autodiscover.exoip.com
                        mail.exoip.com
        Certificate:
                FriendlyName: WMSVC-SHA2
                Thumbprint: A520A23C9032B0D2B62BA812F2DBF91BB580D228
                Lifetime in days: 3555
                Key size: 2048
                Bound to services: None
                Current Auth Certificate: False
                SAN Certificate: False
                Namespaces:
                        WMSvc-SHA2-EX01-2016
        Valid Auth Certificate Found On Server: True
        SMB1 Installed: True
        SMB1 Blocked: False
                SMB1 should be uninstalled SMB1 should be blocked
                More Information: https://techcommunity.microsoft.com/t5/exchange-team-blog/exchange-server-and-smbv1/ba-p/1165615
        Security Vulnerability: CVE-2020-16875
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-16875 for more information.
        Security Vulnerability: CVE-2020-16969
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-16969 for more information.
        Security Vulnerability: CVE-2020-17083
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-17083 for more information.
        Security Vulnerability: CVE-2020-17084
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-17084 for more information.
        Security Vulnerability: CVE-2020-17085
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-17085 for more information.
        Security Vulnerability: CVE-2020-17117
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-17117 for more information.
        Security Vulnerability: CVE-2020-17132
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-17132 for more information.
        Security Vulnerability: CVE-2020-17141
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-17141 for more information.
        Security Vulnerability: CVE-2020-17142
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-17142 for more information.
        Security Vulnerability: CVE-2020-17143
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-17143 for more information.
        Security Vulnerability: CVE-2020-1147
                See: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-1147 for more information.

Exchange Web App Pools
----------------------
        Web App Pool: GC Server Mode Enabled | Status
        MSExchangeServicesAppPool: False | Started
        MSExchangeMapiFrontEndAppPool: False | Started
        MSExchangeOWAAppPool: False | Started
        MSExchangeRestAppPool: False | Started
        MSExchangeMapiAddressBookAppPool: False | Started
        MSExchangeRpcProxyFrontEndAppPool: False | Started
        MSExchangePowerShellAppPool: False | Started
        MSExchangePowerShellFrontEndAppPool: False | Started
        MSExchangeRestFrontEndAppPool: False | Started
        MSExchangeMapiMailboxAppPool: False | Started
        MSExchangeOABAppPool: False | Started
        MSExchangePushNotificationsAppPool: False | Started
        MSExchangeOWACalendarAppPool: False | Started
        MSExchangeAutodiscoverAppPool: False | Started
        MSExchangeECPAppPool: False | Started
        MSExchangeSyncAppPool: True | Started
        MSExchangeRpcProxyAppPool: False | Started

Output file written to .\HealthCheck-EX01-2016-20201227132103.txt
Exported Data Object Written to .\HealthCheck-EX01-2016-20201227132103.xml

The Exchange HealthChecker.ps1 script will generate two files. These files are generated in the same directory of the script. In this example, it’s the folder C:\scripts.

  • 1x TXT file: The txt file is the same as the output in PowerShell. But it’s handy if you want to attach it to an email or place it in a folder.
  • 1x XML file: To better view the XML file, you must run another command to generate a report. See below.
Exchange Server health check files

Generate Exchange health report

[PS] C:\scripts>.\HealthChecker.ps1 -BuildHtmlServersReport -HtmlReportFile "EX01-2016Report.html"

A new EX01-2016Report.html is created in the scripts folder.

Exchange Server health check report in HTML file

Open the Exchange health report EX01-2016Report.

You will see the colors:

  • Grey: Informational items
  • Green: Settings found to match the recommendations
  • Yellow: Settings that give a warning which you can look at
  • Red: Settings that can cause performance problems

The most important ones that you need to take care of are the red ones. Go through it carefully.

Note that most of these recommendations only apply to Exchange 2013/2016/2019. The script will run against Exchange 2010/2007, but the output is more limited.

Exchange health check report

Do you have more than one Exchange Server running? You want to have a report of these Exchange Servers. Let’s have a look at that in the next step.

Generate Exchange health report for multiple Exchange Servers

Get the health report of another Exchange Server. In my example, Exchange Server EX02-2016.

[PS] C:\scripts>.\HealthChecker.ps1 -Server "EX02-2016"

The script created two files in the scripts folder.

Generate the Exchange health report. This time, only use the -BuildHtmlServersReport parameter. It will gather all the XML files in the C:\scripts folder and generate an Exchange health report.

[PS] C:\scripts>.\HealthChecker.ps1 -BuildHtmlServersReport

A new ExchangeAllServersReport.html file is created in the scripts folder.

Exchange Server all servers health report

Generate Exchange health report for all Exchange Servers

Another option is to run the cmdlet to create a report for all Exchange Servers. It will run the HTML report and open it automatically.

[PS] C:\scripts>Get-ExchangeServer | ?{$_.AdminDisplayVersion -Match "^Version 15"} | .\HealthChecker.ps1; .\HealthChecker.ps1 -BuildHtmlServersReport -HtmlReportFile "ExchangeAllServersReport.html"; .\ExchangeAllServersReport.html

If the report does not open automatically, you can find the report in the C:\scripts folder. Open the Exchange Server health report ExchangeAllServersReport.

Exchange health check report

If everything shows green, you are all set. If it’s yellow, look into it. Do you see red items in the Exchange health report? We recommend you to fix it.

Read more: Check Exchange health mailboxes »

Conclusion

In this article, you learned how to check Exchange Server health with the PowerShell HealthChecker.ps1 script. A couple of scripts on the internet will do an Exchange Server health check, but the authors do not keep the script up to date as this one.

In the technology world, you have to provide new features, bug fixes, and adjustments to enjoy the software’s full potential. That’s why I recommend using only this script for an Exchange health check. It’s an excellent PowerShell script that you must have in your collection.

Did you enjoy this article? You may also like Take Exchange Server out of maintenance mode. Don’t forget to follow us and share this article.

ALI TAJRAN

ALI TAJRAN

ALI TAJRAN is a passionate IT Architect, IT Consultant, and Microsoft Certified Trainer. He started Information Technology at a very young age, and his goal is to teach and inspire others. Read more »

This Post Has 18 Comments

  1. I have to admit, the way you deliver is unmatched with any other blog. It’s so simple and easy to understand that I can’t find it more useful in any other post.

  2. Hello, your articles on Exchange, Active Directory, and computer tips are fantastic! Could you cover MFA solutions, especially affordable or free options for enterprises, in your next topic? Your insights would be invaluable. Thanks for your contributions

  3. Hi.
    I have a broken OWA.
    I ran the script and received an error in one of the lines stating that my WebConfig.conf was missing in C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess. Although it is in the required directory and DependentAssemblyGenerator.exe created it. What does it take to fix this problem?

    1. You have to restart IIS or reboot the Exchange Server after applying the change.

      For anyone else reading this, the below commands must be run to recreate the SharedWebConfig.config file in two places.

      Missing SharedWebConfig.config in folder ClientAccess:

      DependentAssemblyGenerator.exe -exchangePath "C:\Program Files\Microsoft\Exchange Server\V15\Bin" -exchangePath "C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess" -configFile "C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\SharedWebConfig.config"

      Missing SharedWebConfig.config in folder HttpProxy:

      DependentAssemblyGenerator.exe -exchangePath "C:\Program Files\Microsoft\Exchange Server\V15\bin" -exchangePath "C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy" -configFile "C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\SharedWebConfig.config"
      1. Yes, of course I used DependentAssemblyGenerator.exe. And file already exist.
        What else could this be? Permissions? Inheriting rights from a directory? Setting up IIS? Somewhere I can look in IIS where the config is explicitly written?

  4. Thanks for your doc.
    It helps a lot.
    Can you please let me know how to send that report thru email to myself?
    I plan to run the script every morning at 6 am.
    Thanks!!

  5. Is it common for the healthchecker script to give false positives on security vulnerabilities? I’ve installed both the May 2022 and Aug 2022 security updates for Exchange 2013 (and ran /PrepareDomain for the May update)…. and in fact, exchange as well as the healthchecker script reports a build of 15.00.1497.040. I can also see “Security Update for Exchange Server 2013 Cumulative Update 23 (KB5015321)” listed in the list of installed updates (HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*)

    But, when I run the healthcheckr script, it lists these vulnerabilities still exist. I did check that I was running the healthcheckr script as ‘admin’ and that I had local admin rights on the local machine…. AND that I had access to directory objects. I’m stumped.

    1. No, it should not give you false positives.

      Installing Exchange Server SU does not mean that the Exchange Server is patched from all vulnerabilities (I know this sounds stupid).

      The Exchange Health Checker script will check for vulnerabilities that are not set with the SU, which you manually have to configure.

      Scroll through the Exchange health report and check if there are “Security Vulnerabilities” errors and fix them, so the Exchange Server is protected.

  6. Hi,

    I want to schedule health check script please help me how to schedule the script.

    Thanks
    Asim

  7. hello Ali

    Good job for the document.
    tanks
    Is is possible to include and run the script thru a firewall to examine two edge servers in workgroup mode ?
    NB: The flow thru the fw is not a true problem.

  8. Ali
    Yet another great read. Well done you 🙂

    tcp/ip setting: not set is all I have outstanding on my check and I cannot find how to resolve this issue
    Does anyone know what to do to get rid of this?

  9. We have Exchange 2013, and when we run the health check the Visual Studio 2013 VC++ is the latest version 12.0.40660 and the report display “Redistributable is outdated”

Leave a Reply

Your email address will not be published. Required fields are marked *