One of the interesting features of Exchange Server 2013 is the way that Managed Availability communicates the health of individual Client Access protocols (eg OWA, ActiveSync, EWS) by rendering a healthcheck.htm file in each CAS virtual directory. When the protocol is healthy you can see it yourself by navigating to a URL such as https://mail.exchangeserverpro.net/owa/healthcheck.htm.
When the protocol is unhealthy the page is unavailable, and instead of the HTTP 200 result above you will see a “Page not found” or HTTP 404 result instead.
Note: there is no healthcheck.htm file in the file system of the server itself.
The healthcheck.htm file is used by the health monitors/probes of various load-balancers and other monitoring systems as a quick and effective way of determining protocol health. For example, if a load-balancer is distributing traffic across four available Exchange 2013 servers and detects that one of them has an unhealthy OWA protocol, it will stop sending OWA traffic to that server.
Recently I've worked on a number of customer support cases for Exchange Server 2013 where the problems they were experiencing were due to one or more of handful of common configuration problems:
- Client Access namespace not well designed or not configured on all virtual directories correctly
- SSL certificates not provisioned correctly
- Load-balancer health monitors/probes failing but not alerting for technicians to investigate
These types of issues are so common that I have been working on integrating them into the next version of my Exchange Server health check script, which is going to be a significant overhaul of the previous version.
In this article I want to share with you some PowerShell that can be used to check your Client Access server health for some of the issues above. Here's a breakdown of how the script works.
- The script collects the various CAS URLs for each site where Exchange is deployed. If multiple URLs are detected for a given service a warning is thrown.
- The script makes use of Invoke-WebRequest to test the Client Access namespaces. There are three possible results tested for so far – “OK” means the healthcheck.htm request returned a HTTP 200 as shown above, “SSL Error” means Invoke-WebRequest failed SSL negotiation, and “Error” is for anything else requiring further investigation.
- Next, the script uses System.Net.WebClient to test each protocol on each individual CAS in the site. This will identify specific servers having problems that may not be evident because a load-balancer or round robin DNS is masking the issues from clients. Using System.Net.WebClient helped to overcome SSL trust issues for the per-server checks, and I could not have worked it out if I hadn't found this blog post by Bhargav Shukla explaining how to handle this scenario.
Right now the script only outputs to the PowerShell console. I am planning to add HTML and email reporting as well, but this may come later as the script is rolled into the next major version of the health check script.
You can download the script from Github. Writing scripts that work for as many scenarios as possible is a challenge, so any questions or bug reports are welcome on Github or the comments below.
Simply run the script on any server or workstation that has the Exchange Management Shell available.
PS C:\Scripts> .\Get-CASHealthCheck.ps1
Here's a few examples of the output you can expect. In this first example the Exchange servers are deployed across two sites. No duplicate CAS URLs were detected, and the per-server health checks were also clean.
In comparison, here is an environment with incorrectly configured CAS namespaces, some SSL errors, and what appears to be an unhealthy ActiveSync protocol.
As I mentioned earlier any questions or bug reports are welcome, either in the comments below or on Github. I'm hoping that this script can be improved with feedback and become a valuable resource for the community.