How many times each day do you get asked, “Is there a problem with the Exchange server?”
If you’re like me then you get asked this question at least once per day. Of course there usually isn’t anything wrong with our Exchange servers 😉 but once the question has been asked then you have no choice but to investigate and confirm that everything is okay.
In this article I’m going to demonstrate how you can quickly check the health of your Exchange Server 2010 mailbox servers, and share a script with you that can help to speed up this task.
Note: a better version of this script is now available here.
Exchange Server 2010 has a series of PowerShell cmdlets that make it easy to do a health check of mailbox servers. For example, we can:
- Run Test-Servicehealth to check the required services are all running
- Run Get-MailboxDatabase to check whether the mailbox databases are mounted
- Run Test-MapiConnectivity to verify that the databases are responding to MAPI requests
- Run Test-MailFlow to confirm that email is able to pass successfully between two servers
- Run Get-MailboxDatabaseCopyStatus for DAG members to check the database copy status, queues, and content indexes
That’s quite a few cmdlets to run, especially if we’ve got more than one mailbox server in the organization. And of course each of those cmdlets needs to run and show you output that you need to interpret.
I like to make life a bit easier and use PowerShell scripts to speed up these types of tasks. So naturally I put together a script for performing all of the above tests (and a few more) on my mailbox servers and display a nice simple colour-coded output so that I can tell at a glance whether there might be a problem.
This isn’t designed to do a diagnosis of any problems, it just checks the fundamentals and gives me a simple pass/fail and a few other indicators that I can then troubleshoot further if necessary.
Note: a better version of this script is now available here.
Extract Test-MailboxServer.ps1 from the Zip file and run it in your Exchange Management Shell to see output such as this:
If you have any questions or bugs to report please let me know in the comments below.
Change log:
- V1.0, 20/11/2011 – Initial version
- V1.1, 10/01/2011 – Fixed $null’s, bugs with Recovery DBs, and ping failure scenarios
[adrotate banner=”48″]
Hey Paul,
is there away to get the up-time in days and not hours? and if yes what would i add to the existing script.
just like everyone here this script is GREAT! i just need to add this one thing for my Boss.
i have changed the SMTP setting but still mails not getting triggred. Do i have to make any other changes in script.
Hello Paul Cunningham
Great script, Thanks for sharing, email not received, how to solve this ?
Awaiting for your reply, Please do the needful
Thanks again
Rudra
HI,
i am getting Error on Test-Mailflow.. how to solve this ?
[PS] C:WINDOWSsystem32>Test-Mailflow
RunspaceId : dd3454e4-ab48-4daa-a7f5-c74a21cccf5d
TestMailflowResult : *FAILURE*
MessageLatencyTime : 00:00:00
IsRemoteTest : False
Identity :
IsValid : True
Pingback: Create an Exchange Mail Flow Latency Heat Map with PowerShell
Hi Paul.
Thanks again for another great article.
In an environment where all databases in the DAG are mounted on a single DAG member would test-mailflow always give *Failure*
Does it have to be able to send between mailboxes on separate servers to succeed?
The Real Person!
The Real Person!
Yep, if I recall correctly if there’s no active databases on a server then the mail flow test will fail. I thought I had accounted for that and replaced the failure with an “n/a”. Are you using the latest version of Test-ExchangeServerHealth.ps1 from TechNet/Github?
That’s great thanks. No, was just curious, as noticed that running the individual command always gave a *Failure* and was concerned that there was an issue somewhere.
Really appreciate the response.
Thanks again
Hey Paul, this works perfectly. Thanks a lot !!
On the public folders part, I had used the wrong word “decommissioned”, it was actually never in there. But the PFDB was there which has been dismounted recently. Please let me know if it still may cause us some issues leaving it in dismounted state in long run if we never had or plan to have public folders.
Thanks a ton.
The Real Person!
The Real Person!
“…it was actually never in there. But the PFDB was there…”
Now I’m confused. Either the public folder database exists or it doesn’t.
If it exists and you want to decommission it completely, don’t just leave it dismounted.
Hi Paul,
In our environment, since Public Folders have been decommissioned, we have dismounted the public folder database. Is there a way we can remove the alert for public folder database dismounted on this script?
I have tried adding it to the ignore.txt file but that does not help.
Kindly suggest.
Thanks!!
The Real Person!
The Real Person!
You could take the Get-PublicFolderDatabase line out of the script.
But I would suggest to you that dismounting the PF database is not the same as properly removing public folders from your organization. Leaving it in that state is likely to cause you issues in the long term.
Hi Sir,
I was successful in installing exchange server 2013 sp1 on windows server 2012r2.After that i restarted my server and entered administrator credentials in the eac ,i am getting http error : 500 internal server error. and nothing is displayed on the page.
Brill little script, well not so little, helped fix some minor issues on the service.
I need to schedule this script so it sends a report to another team, I know there is something I can do so it automatically sends the report but I cannot find the right bit. Any chance of sending me the code.
Again excellent script.
Bill
The Real Person!
The Real Person!
A better version of the script is here:
https://www.practical365.com/powershell-script-health-check-report-exchange-2010
After you join and login and download the script, on that page there is also directions for scheduling the script with Task Scheduler.
Greate Article. Paul. It helps.
Pingback: punjabolx.in
HI Paul, great script thank you. one issue though,
The script can not send email notifications when a vital service like the transport service is off if the smtp settings used are for the internal server and the environment has only one server, how can the smtp setting be changed to accommodate external smtp settings like for google that may require authentication.
thank you.
Pingback: Exchange Mail Flow Latency Heat Map with PowerShell
Pingback: maigrir des cuisses vite
HI Paul,
I have just one server (mbx, hub and cas) and i’m getting this error:
Add-Member : Cannot bind argument to parameter ‘name’ because it is null.
Note: I,m running it on the same server where exchange 2010 is installed (windows 2008 r1)
Any idea?
Regards
JO
The Real Person!
The Real Person!
Run the script with the -Log switch and then email me the log file to paul at practical365.com and I can take a closer look. If possible attach one of the report emails as well so I can see the HTML results too.
Hi Mate
Thanks for the script!!!
Have a good day.
Cheers
Rosh
i noticed that once the script finds a mail server with a high copy/replay count (like a lagged database copy server), all the remaining servers after that are also shown in red, even though they do not have this issue. I don’t believe that variable is being reset in your loop through the server list 🙂
Another issue, when i pass a server name at the command line instead of letting it run through all of our servers, the mail flow test fails with:
Mail flow test: Skip, no active mailbox databases
Cannot bind argument to parameter ‘Server’ because it is null.
+ CategoryInfo : InvalidData: (:) [Get-MailboxDatabaseCopyStatus], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Get-MailboxDatabaseCopyStatus
The Real Person!
The Real Person!
Hi Brian, thanks for that. I’m no longer maintaining this script as there is now a much better one being developed here:
https://www.practical365.com/powershell-script-health-check-report-exchange-2010
I should probably just remove the download links from this page to avoid confusion 🙂
Hi Paul,
Thanks for the new script link. Can you please send me the command that how i can check and test the incoming and outgoing emails on the exchange server 2010.
I am Sorry. i forgot to mention the script i am using.
Its Test-ExchangeServerHealth.ps1
Thanks
The Real Person!
The Real Person!
For backup checks I suggest using this script:
https://www.practical365.com/set-automated-exchange-2010-database-backup-alert-email/
Thanks.
Hi Paul,
Thank you for the script. It is working fine.
I just wanted to add two more colums LatestFullBackupTime and LatestIncrementalBackupTime
I tried hard but no luck.(I dont have much idea about scripting)
Could you please suggest
Thanks in advance
Anant
Hey.
My Exchange 2013 was working pretty well. After I deployed Sharepoint 2013, exchange got broken. First it was Port issue. I changed sharepoint’s. Now Exchange PowerShell Connects without a problem. running your script, it only shows dismounted mailbox failure and not checking mounted one. Running Test-MailFlow, It shows Failure. I’m talking general? I know, but any suggestion?
The Real Person!
The Real Person!
You’ve installed Sharepoint on the Exchange server? I don’t recommend you do that. I’ve never tried it myself, so I have no idea what exactly it will break and how to work around it.
Pingback: Health Check an Exchange 2010 Mailbox Server | Welcome @ VSPBreda
Thanks for a great script.
🙂
I like the script, BUT it does not properly reflect DAG health. As noted below, your script shows everything Passed, but when we ran Test-ReplicationHealth the QuorumGroup check failed with an error on the DAG. Something to include in a future revision is Replication Health.
—— Checking MBXP01
DNS Check: Pass
Server up: Pass
Uptime (hrs): 2
Server version: Exchange 2010
Roles: Mailbox
Mailbox Server Role Services: Pass
Public Folder databases mounted: Pass
Mailbox databases mounted: Pass
MAPI connectivity: Pass
Mail flow test: Success
Hi Paul,
How to run the script for individual mailbox server , i mean where to modify the script.
Pingback: Exchange Server 2010 – Failover & Maintenance | FICILITY.NET
Hi Paul,
This is wonderful script. It made my monitoring much easier. Please keep up with your good scripting work.
Thanks Once again.
Pingback: Test-ExchangeServerHealth – PowerShell Script to Generate a Health Check Report for Exchange Server 2010 | Yusuf Mangera
Pingback: PowerShell Script: Generate an Exchange 2010 Health Check Report
Pingback: Create an Exchange Mail Flow Latency Heat Map with PowerShell
in polish enviroment i’ve got ‘powodzenie’ (means success) in red color – Mail flow test: Powodzenie
Great Scipt man! We use it all the time. Really appreciate the Go-Giver mentality!
Sunny Lowe
Hi Paul
Also we daily running command to get the item count for journal mailbox
get-mailboxstatistics -identity “Journal Mailbox Name” | select itemcount
Can be include in this script? It would be great full if you add the above command in the scripts and relase.
also as my previous request, The result should be goes to email via HTML fomat or it can be same result as in the on screen but it shd be send the email to exchnage admin
so that we can schdeule this script in task and runs daily in the morning ,and all our exchange admins get the result via Email , instead of running the script manually
I hope you understood our request.
Hi Paul
Is there anyway to send the result in HTML formatl via Email as Health Check Report
Pingback: Ehlo.ws – Exchange related blog - How to Health Check an Exchange 2010 Mailbox Server
Hi Paul,
great job. Big thx for the script. When can we expect a test script for the other exchange roles 🙂
Hello,
Great script. Thanks a lot.
Max.
Tks Paul…
Tks Paul, its a great job…
One question do you have any script to check the performance of Exchange Server 2010 on and typically installation method.
Best regards,
The Real Person!
The Real Person!
For performance checks I use ExPerfwiz:
http://archive.msdn.microsoft.com/ExPerfwiz
And then use this article to guide me through the analysis of the data.
http://technet.microsoft.com/en-us/library/bb201720(v=exchg.80).aspx
Thanks for the script. Looking forward for your next version. Sending an email alert to admin in the event of “RED” result would be nice.
I figured it out. I had to include . in front of the command. Why?
The Real Person!
The Real Person!
Hi Tom, thats just how PowerShell scripts are executed, by using…
.script-name.ps1
There’s some more info here:
http://technet.microsoft.com/en-us/library/ee176949.aspx
Why they designed it that way I don’t know, its just how it is 🙂
I don’t want to sound like a goober but when I try to run the script I get the following error:
The term ‘Test-MailboxServer.ps1’ is not recognized as the name of a cmdlet, function, script file……….
What am I doing wrong?
First of all, thanks for the script. is great.
when I try to export the script output to a file, it is empty. Do You know the reason?
I use this command:
C: Scripts>. Test-MailboxServer.ps1 | ConvertTo-Html | Set-Content C: Scripts Logs Test-MailboxServer.html
Sorry if my question is a bit silly
Thanks for everything
The Real Person!
The Real Person!
Not silly, the script is a bit lazy and just uses Write-Host to output to console. It wasn’t originally written with nicely formatted reports in mind 🙂
I’ll be updating it with proper PS objects and such so that HTML output is a possiblity, among other planned improvements.
Thanks for your time.
I’m testing with the command Start-Transcript-path C: Scripts Logs Test-MailboxServer.csv at the beginning of the script and Stop-Transcript to end.
It seems to work fine. Now I just send it by email.
Thanks for everything.
Pingback: Using Test-Mailflow with Exchange 2003 Servers
Thanks for this great script, very useful indeed!
Could you add:
1. Test-OutlookConnectivity (Protocol:TCP and HTTP)
2. Test-SmtpConnectivity
3 .Test-replicationhealth
4. Queue reporting (Get-TransportServer | Get-Queue)
it will be the best choice for any Exchange admin since it is a perfect combination of functionality and beauty.
Thanks again for your great work !
The Real Person!
The Real Person!
Sure thing, I’m working on a script to health check all the server roles in the org.
Hi Paul,
Great script, but I found one small bug.
On line 254:
$IsDAG = Get-MailboxServer $server.name
generates an error when a single server name is supplied as an argument on the command line, because it’s just a string instead of an exchange server object. When no argument is supplied, you do a Get-ExchangeServer to retrieve all of the servers, but when an argument is supplied, you’re not doing anything with it.
Change line 56 from:
$mbservers = @($server)
to this:
$mbservers = @(Get-Exchangeserver $server)
and that will fix it right up.
Thanks again,
Mike
The Real Person!
The Real Person!
Thanks Mike.
Great Script – ran perfectly. I think I’ll tweak it and add the email functionality.
Once again another great article.
Hi Paul,
Works great, Thanks for sharing
Hi Paul,
Good day to you! Just wondering if you have the new version to send the script thru email?
The Real Person!
The Real Person!
Hi Dax, not yet. I’ve just returned from holidays this week though, and I’ve got a lot of improvements planned for the script including email functionality, so stay tuned 🙂
HI Paul
Am running this script under my lab 2010 which is having 2 Mailbox Server and NO DAG is implemneted till..
When i ran the script it from the C: drive in server name SRV1
it showing as
Checking SRV1
Ping test:—–Checking SRV2
Ping Test: [PS] C:\>
What is the issue
The Real Person!
The Real Person!
Are you running it in the Exchange Management Shell or just a Powershell session?
Hi Paul
Am running this From Exchange Mgmt Shell.
The Real Person!
The Real Person!
Hi Ram, sorry for the delay. I get that same problem if I try to run the script for a server that doesn’t exist. I guess that means the ping fails and the script is not handling that properly.
So it could be that in your case the ping is failing too, perhaps due to a firewall? Can you ping the servers normally from the computer that you’re running the script on?
The Real Person!
The Real Person!
Ram, I’ve updated the script to V1.1 with better handling of failed ping scenarios. Please try the new version and let me know how you go.
Hi Paul,
its working fine..I want to send this report as an email. Please let me know to proceed??
The Real Person!
The Real Person!
Hi Jagan, I’ll see about adding that as an enhancement in the next version, but if you don’t want to wait you can go ahead and learn about sending email reports from scripts using my tutorial series starting here:
https://www.practical365.com/powershell-how-to-send-email
Hello Paul, Thanks !!! I will try to write the script to send an email….
Thanks
Nice script
Thanks Paul.
Hi Paul,
Test-Mailflow on this server gives me the error: Unable to open message store.
This server does have a recovery database on it. Is that the cause of the error?
Thanks,
Kevin
The Real Person!
The Real Person!
Yep that looks like the cause, I just need to update the script to deal with that scenario.
The Real Person!
The Real Person!
Hi Kevin, I’ve put some RDBs in my test lab and can’t seem to reproduce the error you’re getting. Could you please try downloading the new version of the script and trying again?
Also, when you’re running the script are you running it on the server that only has an RDB on it, or do you see the error when you run the script on another server or on your own workstation?
Hi Paul,
I’ll download the latest build and try it later.
Thanks,
Kevin
Hi Paul,
Cool script, I’ll definitely be keeping it on hand.
Just one quick note on using $nul as opposed to $null: $nul is settable like any other variable, $null is and always will be null.
If someone has, for whatever reason, set $nul to a value, this could play havoc with some scripts.
Cheers,
Chris
The Real Person!
The Real Person!
Good catch, I’ll fix that up in the next update.
The Real Person!
The Real Person!
Fixed in V1.1
Hi Paul,
I just remembered that there is one active database on that server. There are no copies of the database anywhere. This is the error message I get for that server.
Kevin
ERROR MSG:
Mail flow test: [Microsoft.Mapi.MapiExceptionRecoveryMDBMismatch]: MapiExceptionRecoveryMDBMismatch: Unable to open message store. (hr=0x80004005, ec=1165)
+ CategoryInfo : InvalidData: (:) [Test-Mailflow], RecipientTaskException
+ FullyQualifiedErrorId : DB35BF00,Microsoft.Exchange.Monitoring.TestMailFlow
The Real Person!
The Real Person!
Is there a recovery database on that server as well?
What happens if you just run Test-MailFlow for that server?
Hi Paul,
Great script. Thanks for sharing. It works great on all the mailbox servers in my DAG except for a server that I have that only holds passive database copies. On that server the mail flow test fails with an unable to open message store. Not a big deal, I was just wondering if you knew why.
Thanks again.
Kevin
The Real Person!
The Real Person!
Makes sense if there are no active databases on that DAG member then it can’t perform that test. I’ll update the script to skip that test when there are no active DBs.
Thanks. Changed it to unrestricted, ran the script, then changed back to remotesigned.
Hi! I get the following error: The file xxxxxxx is not digitally signed. The script will not execute on the system.
The Real Person!
The Real Person!
Yep, the script isn’t signed. You can change your execution policy to get around that, see here:
http://technet.microsoft.com/en-us/library/ee176961.aspx
Hi! I get the following error:
VERBOSE: Connecting to Ex01.Welsoft.local
VERBOSE: Connected to Ex01.Welsoft.local.
The operation couldn’t be performed because object ‘DAG-01.Welsoft.local’ couldn’t be found on ‘DC01.welsoft.local’.
+ CategoryInfo : NotSpecified: (:) [Get-ExchangeServer], ManagementObjectNotFoundException
+ FullyQualifiedErrorId : 3D32AE05,Microsoft.Exchange.Management.Syste
The Real Person!
The Real Person!
Which script are you running, and what is the exact command line you’re using?
Test-ExchangeServerHealth.ps1 V1.07, 24/11/2013
.Test-ExchangeServerHealth.ps1 -ServerList serverlist.txt -ReportMode -SendEmail
The Real Person!
The Real Person!
In your serverlist.txt have you included a DAG name? That won’t work. Only server names can go in that list.
But we have more than 30+ DAG’s available on our environment, in that we need to monitor only one DAG. Rest of the DAG’s we need to ignore it.
The Real Person!
The Real Person!
You can ignore all the other DAGs by adding their names to the ignorelist.txt file.
Thanks.. Let me try..
I have added other servers(like ..EX08,EX09) and all other DAGs (like DAG-06, DAG-07 in Ignorelist.txt file. but still i got error.
************************************************************************************************************
An Active Manager operation failed. Error An error occurred while attempting a cluster operation. Error: Cluster API ‘O
penByNames(‘EX-08.Welsoft.local’, ‘EX-09.Welsoft.local’) failed for each server. Specific exceptions: ‘An
Active Manager operation failed. Error An error occurred while attempting a cluster operation. Error: Cluster API ‘”Op
enCluster(EX-09.Welsoft.local) failed with 0x6ba. Error: The RPC server is unavailable”‘ failed..’, ‘An Active M
anager operation failed. Error An error occurred while attempting a cluster operation. Error: Cluster API ‘”OpenCluster
(EX-08.Welsoft.local) failed with 0x6ba. Error: The RPC server is unavailable”‘ failed..’.’ failed..
+ CategoryInfo : InvalidArgument: (:) [Get-DatabaseAvailabilityGroup], AmClusterApiException
+ FullyQualifiedErrorId : 9BBFD80B,Microsoft.Exchange.Management.SystemConfigurationTasks.GetDatabaseAvailabilityGroup.
***********************************************************************************************************
The Real Person!
The Real Person!
Please run the script with the -Log switch and email me the log file that it produces. Address is paul (at) practical365.com