This PowerShell script will perform a health check of your Exchange Server environment, including servers and database availability groups, and output a HTML report that you can send to your inbox.
The report includes a summary of issues that were found, as well as a color-coded table with the detailed test results to help you quickly spot problems.
This is a useful script to run as a daily health check first thing in the morning to identify any problems that may have occurred overnight, and give you a chance to fix them before your end users notice.
This script is available to download from the TechNet Script Gallery or Github. Comments are welcome below. If you find a bug please consider raising it as an issue on Github.
Script parameters:
- -Server, Perform a health check of a single server
- -ReportMode, Set to $true to generate a HTML report. A default file name is used if none is specified.
- -ReportFile, Allows you to specify a different HTML report file name than the default.
- -SendEmail, Sends the HTML report via email using the SMTP configuration within the script.
- -AlertsOnly, Only sends the email report if at least one error or warning was detected.
- -Log, Writes a log file to help with troubleshooting.
Examples:
.\Test-ExchangeServerHealth.ps1
Checks all servers in the organization and outputs the results to the shell window.
.\Test-ExchangeServerHealth.ps1 -Server HO-EX2010-MB1
Checks the server HO-EX2010-MB1 and outputs the results to the shell window.
.\Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
Checks all servers in the organization, outputs the results to the shell window, a HTML report, and emails the HTML report to the address configured in the script.
If you use the report mode you’ll get a HTML file containing the health check results, and/or an email to your designated address if you also use the send email option.
For the email functionality to work please update these variables in the script to suit your environment.
#................................... # Modify these Email Settings #................................... $smtpsettings = @{ To = "administrator@exchangeserverpro.net" From = "exchangeserver@exchangeserverpro.net" Subject = "Exchange Server Health Report - $now" SmtpServer = "smtp.exchangeserverpro.net" }
When running the script on non-English servers you can modify the following variables in the script to match your language so that the script does not give errors or incorrect results.
#................................... # Modify these language # localization strings. #................................... # The server roles must match the role names you see when you run Test-ServiceHealth. $casrole = "Client Access Server Role" $htrole = "Hub Transport Server Role" $mbrole = "Mailbox Server Role" $umrole = "Unified Messaging Server Role" # This should match the word for "Success", or the result of a successful Test-MAPIConnectivity test $success = "Success"
For example, a German system would use the following values:
# The server roles must match the role names you see when you run Test-ServiceHealth. $casrole = "Clientzugriffs-Serverrolle" $htrole = "Hub-Transport-Serverrolle" $mbrole = "Postfachserverrolle" $umrole = "Unified Messaging-Serverrolle" # This should match the word for "Success", or the result of a successful Test-MAPIConnectivity test $success = "Erfolgreich"
Use the ignorelist.txt file to specify the names of any servers, DAGs, or databases that you want to ignore for the tests.
My scheduled task settings for this script are:
- Run whether user is logged on or not
- Run with highest privileges
- Action: Start a program
- Program: powershell.exe
- Arguments: -command “C:\Scripts\ExchangeServerHealth\Test-ExchangeServerHealth.ps1 -Log -SendEmail”
FAQ
Q: Which version of PowerShell is required?
If you are running the script on a server that has Exchange 2010 or 2013 (or later) server roles or management tools installed then it should work.
Q: I’m running multiple versions of Exchange, will the script still work?
Yes, it should work as long as you run it from the highest version of Exchange. For example, in a mixed Exchange 2010/2013 environment you should run the script from an Exchange 2013 server.
Q: Why do I get an error when the script sends the email report?
Make sure you’ve configured the email settings section of the script to point to a Hub Transport that either accepts anonymous users (typically an internet-facing Hub Transport), or if you’re using a separate management server or admin workstation point the SMTP server to a Hub Transport that has a receive connector set up that the server you’re running the script on is allowed to relay through.
Q: Why aren’t Edge Transport servers checked?
Between firewalls and permissions the Edge Transport checks are difficult to account for so they are currently skipped by the script.
Q: What should I do when the script report an error/fail on my servers?
The script doesn’t perform any diagnostics when it detects an error, it only reports them to you. When you see an error you should investigate further using the management tools and cmdlets that are provided by Exchange.
If you are encountering situations where the script reports errors that turn out to be false alarms please let me know and I will do my best eliminate those false alarms.
Q: Can you add feature X to the script?
If you have additional requirements then you are encouraged to customize the script to suit your own needs.
[adrotate banner=”48″]
The Real Person!
The Real Person!
Is there a way to export the result from the PS console to JSON file?
The output of the script is a HTML file. It’s built up from arrays like $dagdbcopyReport. You could export the source arrays to JSON using the ConvertTo-JSON cmdlet.
Cannot process argument transformation on parameter ‘Server’. Cannot convert the “” value of type
“Deserialized.Microsoft.Exchange.Data.Directory.Management.ExchangeServer” to type
“Microsoft.Exchange.Configuration.Tasks.ServerIdParameter”.
Im getting this error …any one know why
Hi Guys,
We are running the script on a 2016 Exchange Server, unfortunately after the last update last week all the MAPI Tests failed. Do you have any idea? If I run the test manually it’s ok.
Thanks ;-).
Hi there. Read this, it may explain your situation. I am also experiencing the same issue.
https://learn.microsoft.com/en-us/answers/questions/1426987/exchange-2016-ecp-powershell-error-after-last-cu-u
i try to run script from remote a server, how can i run it ?
Hi,
Thanks for the script. We have deployed 2019 serevrs so it is the same. i have ran the script against the server But it is showing as 2013 only servers as . anything i needto modify
i try to run script from remote a server, how can i run it ?
Hi Paul,
Thank you for the wonderful script. Is there a way to exclude content index health check because its No longer applicable to Exchange 2019 databases. The report contains the following :-
Database Availability Group Health Check Summary
The following DAG errors and warnings were detected.
Database01- unhealthy content index count is 4 (of 4 )
Page through the history here and you’ll find this entry. November 22, 2019. You’re solution is there.
Franck Ehret says
November 22, 2019 at 9:52 pm
In fact, somebody arlready did :
https://github.com/cunninghamp/Test-ExchangeServerHealth.ps1/pull/36/commits/7a8fc75e0ec3135649b1c7243c19550b7f156a52
Seems to work fine 😉
Hello Paul.
Amazing script. Very useful to quickly identify what is wrong in big environments
Is that possible to add Drives capacity and Drive usage percentage with thresholds to be able to predict back pressure?
Thanks
Hello,
Is it possible to run this script as a group managed service account?
Best regards,
Srdjan
I’m getting the following error and I’ve seen in the comments that others have received this too but didn’t see a specific fix…. Any quick suggestions. We have a loadbalancer that the URL will refer to in the error message below.
Mail flow test: WARNING: Connecting to remote server outlook.vonbriesen.com failed with the following error message : WinRM cannot process the request. The following error occurred while using
Kerberos authentication: Cannot find the computer XXXX.XXXXX.com. Verify that the computer exists on the network and that the name provided is spelled correctly. For more
information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the argument, and then try running the command again.
At C:\Healthcheck\Test-ExchangeServerHealth.ps1:452 char:22
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Hi, I had the same error, I am using the same script in the las Exchange 2010 configuration and it work, now using the new Exchange 2016 the mail flow show me a fail test
Tom,
Did you get a fix for this issue? I just added several Exchange 2019 servers to our daily health check script, and they are all failing the mail flow test.
Same here without solution at the moment, did you find one?
Hi,
I was able to adapt the script to make it done.
– In the “Function Test-E15MailFlow()”, line 409 I “null” the $url :
– Comment the line that retrieve the url (it force then to use the given url $url = “http://$e15mailboxserver/powershell”) :
– Running it and it was OK, except for the mailbox server I’m running the script on because it test itself, I then just added a check if I’m on the server running the script to change it
To resume, the beginning of this function is yet :
Function Test-E15MailFlow()
{
param ( $e15mailboxserver )
$e15mailflowresult = $null
$url = $null
Write-Verbose “Creating PSSession for $e15mailboxserver”
# $url = (Get-PowerShellVirtualDirectory -Server $e15mailboxserver -AdPropertiesOnly | Where-Object {$_.Name -eq “Powershell (Default Web Site)”}).InternalURL.AbsoluteUri
if ($url -eq $null)
{
$url = “http://$e15mailboxserver/powershell”
if ($e15mailboxserver -eq “server1”)
{
$url = “http://server2/powershell”
Write-Verbose “URL modified from server1 to $url”
}
Not that it may not be the cleanest way but it run without problems.
Sincerely.
Hello Paul,
Greeting… Great script. I have a question regarding to the ignorelist.txt
I read from previous comments above the format for ignorelist.txt should be
server1
server2
DB1
However, the DB I wish the script to ignore in this format
server1
Exch DB B (<– contain spaces)
I tried to add to the the ignorelist.txt but does not work.
Any suggestions?
Many thanks in advance,
Hi,
We have mixed environment of Exchange 2010 (soon to be decommissioned in DAG) and Exchange 2016 (single server, no DAG, all the mailboxes are moved to O365, serves as a SMTP Server for on-premise applications).
When I run the script in the PowerShell, I get correct details for all Exchange 2010 Mailboxes, DAG, etc.
However none of Exchange 2016 related details (Mailbox Databases in EX-16), are part of the HTML report that is sent.
Is this by design?
Also can I run the script from a remote machine than running within the EX-16 server?
Hi,
I dont know why I’m getting this error. Any idea?
PS C:\Program Files\Microsoft\Exchange Server\V15\Scripts> .\new-TestCasConnectivityUser.ps1 -ReportMode -SendEmail
The only acceptable parameters are in the form of: [-OU ] [-Password ] [-UMDialPlan -UMExtension ].
We applied patches to our server on August 26th and the health check report after that point now says that we Failed the Cluster Network Test. I did a test-cluster and sifted thru the resultant report and only found that it is complaining about us only having one network path. This has always been the case for our Exchange 2016 servers and the test passed before August 26th. Did a Best Practice for Exchange clustering change? or am I missing something?
After Running the cluster Validate the problem seems to have gone away.
Hi Paul,
First I would like to appreciate your work and really most of the time we go through your article only in exchange issues. Appreciated your hard work and contribution.
I want to use this script but when running it getting an error that- Hub transport server role service – failed.
When executed- test-server health – found EdgeSync service is not running and service status is set automatically.
When tried to run edge sync service manually getting the following error
“The Microsoft exchange edge sync service on local computer started and then stopped. some services stop automatically if they are not in use by other services or programs.”
We don’t have an edge sync server role.
Please suggest something to skip edge sync service, so that we can get everything in green color in the report.
Request you to please revert back ASAP, Thanking you in Advance.
Hi,
Mail Test Flow is Fail on the report or i have no problem with this.
All others test are OK.
My Exchange is in French.
Is there an option to change ?
Hello. I have upgraded to Exchange 2016 CU 15 and the Activation Preference is no longer showing.
The line in the script that gets the Activation Preference i is not getting the preference.
$pref = ($database | Select-Object -ExpandProperty ActivationPreference | Where-Object {$_.Key -ieq $mailboxserver}).Value
If I run the script using an Exchange 2010 shell is works but not when it is Exchange 2016. Can someone help me fix the script so I get the preference again.
Hi Paul,
Thanks for such a nice script and it is running fine. But have some queries, i want to skip Public folder checks from the report as we do not have Public folder in our environment.
Could you please help me on it.
Hello Thanks for your script i am trying to migrate exchange 2010 to 2016 i get an error that transport Queue fail on the 2016 server.
Exchange Server Health Check Summary
The following server errors and warnings were detected.
• ICUMBXSVR01 – Unified Messaging Server Role required services not running.
• ICUMBXSVR01 – Transport queue is above high threshold
Database Availability Group Health Check Summary
No Exchange DAG errors or warnings.
Exchange Server Health
Server Site Roles Version DNS Ping Uptime (hrs) Client Access Server Role Services Hub Transport Server Role Services Mailbox Server Role Services Unified Messaging Server Role Services Transport Queue PF DBs Mounted MB DBs Mounted MAPI Test Mail Flow Test
EXCHANGE EvolveEast Mailbox, ClientAccess, HubTransport Exchange 2010 Pass Pass 2915 Pass Pass Pass n/a Pass (12) Pass Pass Success Pass
ICUMBXSVR01 EvolveEast Mailbox Exchange 2016 Pass Pass 735 Pass Pass Pass Fail Fail (7913) n/a Pass Success Pass
Hi Paul / everyone,
Thanks for this script. We’ve been using it on 2010 and it’s been faultless. Just wondering if you could shed some light on an issue with a test on one server:
We’ve added some 2016 servers to our environment, and we’re now running in full coexistence. The checks on 2010 come back ok, but on the 2016 servers, everything shows as well PASS except for the mailflow check on our first 2016 server, which comes back with:
Mail flow test: WARNING: Couldn’t perform the operation because the server “xxxx” isn’t a Mailbox server.
The issue is that the server it references is a CAS server in the 2010 environment. All other 2016 servers pass the test ok.
Any ideas what’s going on?
Found the issue – the internal powershell URL for that server in ECP was mistyped and was pointing to the old CAS server (only 1 letter difference in the name). Problem solved !!
Works great with 2016 and below.
Added this for 2019.
if ($ExVer -like “Version 15.2*”)
{
$version = “Exchange 2019”
}
Since indexes are internal, it shows indexes are failed when they just don’t exist externally anymore. Should be a fairly easy thing to change. I’m working through that now.
I’ve just started 2019 migration and noticed that as well… 🙂
I’ll really appreciate the updated version !
In fact, somebody arlready did :
https://github.com/cunninghamp/Test-ExchangeServerHealth.ps1/pull/36/commits/7a8fc75e0ec3135649b1c7243c19550b7f156a52
Seems to work fine 😉
Worked for our Exchange 2019 as well.
hi experts
how send to multiple email address?
A lot of people ask how to add multiple recipients to the SMTP settings. My advice is to use a distribution group, so that any time you need to modify the list of recipients you can simply change the distribution group membership instead of needing to modify the script code.
Warning Occured: he term ‘Test-Mailflow’ is not recognized as the name of a cmdlet, in the exchange server version 2016. Below are the output result.
[PS] C:\Windows\system32>C:\Scripts\Exchange_Health-Check.ps1
Initializing…
—— Checking EXCHANGE-2016
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 74
Server version: Exchange 2016
Roles: Mailbox
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 23
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: WARNING: The term ‘Test-Mailflow’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was inclu
ded, verify that the path is correct and try again.
Fail
—— Finishing
Done.
Thanks for the Great Script Paul.
However I see that the Lagged copies are not properly getting captured and is not writing the correct value for $replaylag variable (I’m on Exchange 2016 CU12)
I fixed it by editing the right property –
Old Value – if ($replaylagcopy.Key -ieq $mailboxserver)
New Value – if ($replaylagcopy.Key.Name -ieq $mailboxserver)
I think the same applies for the $truncatelag as well.
New Value – if ($truncationlagcopy.Key.Name -eq $mailboxserver)
Hello Paul,
Thanks for your the great script!
I am using Chinese language in my Windows server 2012, and I don’t understand your script about “localization strings”, do you know how can I set my language?
Could you please give some tips?
Thank you!
Add chinese role name like below
# The server roles must match the role names you see when you run Test-ServiceHealth.
#英文名称 $casrole = “Client Access Server Role”
$casrole = “客户端访问服务器角色”
#英文名称 $htrole = “Hub Transport Server Role”
$htrole = “集线器传输服务器角色”
#英文名称 $mbrole = “Mailbox Server Role”
$mbrole = “邮箱服务器角色”
# $umrole = “Unified Messaging Server Role”
Dear Paul,
Thanks a lot for your valuable articles and tips, please can you update the Health Check Script to run with Exchange 2019…
Current script is not detecting correct Exchange version, also showing warnings on DAG Databases health check as unhealthy content indexes.
Regards.
Hi Paul,
I want to run the HealthCheck script for our Edge server and also want to provide input file for the list of server. Help me with this.
Hi Paul,
I was run the HealthCheck script for our Edge server and also want to provide input file for the list of server. Help me with this.
Fine way of telling, and good post to obtain data about my presentation topic, which i am going to convey in institution of higher education.
Useful information. Fortunate me I found your website accidentally, and I
am shocked why this coincidence didn’t came about in advance!
I bookmarked it.
Hi Paul,
I have below queries regarding script:
• The script is for Exchange 2010 and up, but doesn’t account for the fact that ServerRole values has changed since 2010. This is why it’s showing Hub Transport as failed, although why it thinks Client Access is good is a bit of puzzle. We’ll either have to remove or alter that part of the script so it’s not showing false errors
• The script PowerShell Logon section needs to be re-written to work as Automatic Task. How can this be done?
• The script is showing a lot of Replay Queue errors, I believe these are caused by the Lag Copy databases we have. How to deal with this?
Hello,
nice script btw. However I get the following error when I execute the script:
Mail flow test: WARNING: Connecting to remote server mail.hisolutions.com failed with the following error message : WinRM cannot
process the request. The following error occurred while using Kerberos authentication: Cannot find the computer
mail.hisolutions.com. Verify that the computer exists on the network and that the name provided is spelled correctly.
For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:\org\exchange\Test-ExchangeServerHealth\Test-ExchangeServerHealth.ps1:452 char:22
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
I have a Exchange Server 2016 DAG with two servers. and a standalon server running Exchange 2013 running in the same organization. The OS of the exchange 2016 is Windows server 2016
Rgds
Haydar
Hey haydar, I had the same problem. However, as per suggestion from Mark before the past, if you comment out
$url = ….. from (around) line 418
does this solve your problem?
Hi Paul, many thanks for this very useful health check script, just had a quick question regarding the exclusion file.
I have no issue listed servers that I want to exclude, however I have a challenge listing some databases to exclude, i.e I have some restore DBs which are unmounted and want to exclude them from a couple of servers but listing the database names don’t seem to work.
Could you advise what is the correct format to allow this to work.
Thanks, Fred
Paul this script has been very useful as have the other scripts which you have compiled. Thank you very much for the time taken to create this script
Paul, this script is awesome, thank you so much… We have been having issues with our environment and this at least gives a heads up before the users report problems.
hi friend,
but when i run this script , i have error
Mail flow test: WARNING: Connecting to remote server srv-XX failed with the following error message : The WinRM client cannot proces
s the request. The WinRM client tried to use Negotiate authentication mechanism, but the destination computer (SRV-XX:80) returned a
n ‘access denied’ error.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or emp
ty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the argument, and
then try running the command again.
At C:\Users\aslaniadm\Desktop\Test-ExchangeServerHealth.ps1:452 char:22
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
—— Finishing
why this occurred and what can i do ?
The script fails on the mail flow test with the following … any idea why?
Mail flow test: WARNING: Connecting to remote server xxx.xxxxxx.com failed with the following error message : WS-Management cannot process the request. The
operation failed because of an HTTP error. The HTTP error (12152) is: The server returned an invalid or unrecognized response . For more information, see
the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or empty, and then try the
command again.
Hi Paul,
Good day!
I was using this script and it works perfectly but after moving my mailbox database from the default path to drive D I kept on getting an error/warning “Could not test service health. ” I don’t want to ruin the script since I am new to exchange. But if I need to, can you please tell me where in the script should I change the path or directory.
Thank you,
Chi
Hi, Paul:
Very useful script thanks a lot.
my issue is in exchange server 2016 the default online search limitation is 250…but i need to increase the search limitation to 2000.
Hi Paul;
I wanted to add the following commands to the report but failed. Can you help me with this?
Get-MailboxDatabase -Status | sort name | select name,@{Name=’DB Size (Gb)’;Expression={$_.DatabaseSize.ToGb()}},@{Name=’Available New Mbx Space Gb)’;Expression={$_.AvailableNewMailboxSpace.ToGb()}}
Thank you for making the report. 🙂
Good morning Paul,
thank you for the great script.
Unfortunately I get 2 different results.
The problem ist the mail flow test.
The log says ‘Mail flow status is Erfolgreich’
The html Check Report says Mail flow test failed. (in red)
Any solution?
Regards
Stephan
Hi Paul, we have been using this script daily to check on our environment. I am currently on Exchange 2016 / 2010 co-existence. I updated Exchange 2016 to CU11 this weekend and now the script is showing null value errors for
“You cannot call a method on a null-valued expression.
At D:\Scripts\Test-ExchangeServerHealth2\Test-ExchangeServerHealth.ps1:1575 char:17
+ $DagMemberVer = ($GetExchangeServerResults | Where-Object {$_.Na …”
This was working fine with Exchange 2016 CU9. The printed report has no names under the server column in the DAG sections and the Exchange 2010 Dags show the “server locator service” Failed on every Exchange 2010 server. I reviewed each Exchange 2010 server using Test-Replicationhealth and the error does not show up there.
Ideas?
Curious if you ever solved your “no names under the server column” problem … we were a few CU’s behind and just installed CU12 … and are see the same now too. Also seeing blanks for “Preference” related columns … I assume it’s related.
I was running the script from a management server … once I updated that server with CU12 the script started working properly again. Happy to see it working again.
Hi Paul
Great article as always, but just came across an interesting issue in a test environment, when the server name isn’t all in upper case. This resulted in the script being unable to report on activation preferences of the database copies.
The following line in your script was attempting to perform a case-insensitive comparison between server names, but if they weren’t exactly the same case, it wouldn’t return any results.
$pref = ($database | Select-Object -ExpandProperty ActivationPreference | Where-Object {$_.Key -ieq $mailboxserver}).Value
I needed to specify the “Name” property of the “Key” for this to work correctly:
$pref = ($database | Select-Object -ExpandProperty ActivationPreference | Where-Object {$_.Key.Name -ieq $mailboxserver}).Value
Cheers
Another Paul
Hi Paul, thanks for this useful script.
Have you already test it on Exchange 2019 ?
Same question for the DAG Health check ? 🙂
Thanks,
Regards
Hello Paul,
I found the solution
It is “Server Management” and “Remote Management Users” roles.
Regards
Hello Paul,
When we try to run script it gives an error below;
Mail flow test: WARNING: The term ‘Test-Mailflow’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Fail
It was working fine but we accidentilly remove running users groups.
Can you help us to work again?
Thank you for great script.
Regards.
Terrific script! It has everything I need except disk space. Would that be a feature to add later? I’ve tried to add it myself, but broke many things within.
Thanks for the awesome work!
Hi Paul, great script, we have been using this for production use with Exchange 2016 CU9.
After recently installing CU10, the Server name column under “Database Availability Group ‘DAG’ Member Health” is now coming up empty. All the other boxes still pass
Do you have any idea why this would stop this working?
Looking in the code that first row appears different to all the others:
$htmltablerow += “$($line.”Server”)”
$htmltablerow += (New-DAGMemberHTMLTableCell “ClusterService”)
$htmltablerow += (New-DAGMemberHTMLTableCell “ReplayService”)
Thanks
Fantastic Script!!
I am having 1 issue however.
I am currently running a Exchange 2010-2016 co-existence environment. 1 of my Exchange 2016 servers shows a “Unable to Retrieve Uptime” message. All other servers are working fine.
Any ideas on what is not working?
Hi,
I would like to ignore a specific database but it doen’t work.
How do I specify database in ignore.txt file ?
database/server
or
database
I try both but it doen’t work.
Thx
For anyone who is running into problems making this script work with Task Scheduler, I got it to work. Initially using the author’s instructions, it did not work. Task Scheduler said that the task completed successfully almost instantly, but the script did not run.
I’m running this on a Server 2016 / Exchange 2016 CU10 server.
– Run As: (my domain Exchange Admin account)
– Run whether user is logged on or not
– Run with highest privileges
– Configure for: Windows Server 2016
– Start a program
– Program/script: Powershell.exe
– Add arguments (optional): -ExecutionPolicy Bypass C:\Scripts\Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
– Start in (optional): blank
I messed around with a bunch of the settings, but I believe the main issue I was having related to not having the ExecutionPolicy, plus trying to use -command “script path+name+params”. You don’t need any quotes in the “Add arguments” section.
Hope this helps anyone else who wanted to schedule this awesome script! Thanks again for making it and maintaining it for us!
Thank you so much
Just a note: I have been using this script since it came out. I had 2010 and 2016 exchanges servers. I just finally removed my one exchange 2010 server. Everything went fine. My question is this script is still showing the removed exchange 2010 server in the results. Do I have to wait a day or so after removing DNS, AD, etc. related to the removed server?
Thanks.
Bill
C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\data\Queue>”C:\Pro
gram Files (x86)\Log Parser 2.2\logparser.exe” “SELECT data as [Status Code],Cou
nt(*) as Hits FROM *.log WHERE data LIKE ‘5%’ GROUP BY data ORDER BY Hits DESC”
-i:CSV -nSkipLines:4 -rtp:-1
Error: SELECT clause: Syntax Error: unknown field ‘data’
To see valid fields for the CSV input format type:
LogParser -h -i:CSV
if anyone’s getting the mailflow test failure, check the servers NIC card has Register DNS Ticked (not normally set for a server with static address) as exchange mailflow requires this, you then get a clean bill of health
I finally got Email to work! However, the htmlreport does not generate when running with PowerShell directly or running a scheduled task. I have to run it in C:\Scripts by running .\Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail. Any suggestions?
###########Define Variables########
$fromaddress = “ExchangeReport@yourdomain.com”
$toaddress = “username@yourdomain.com”
$Subject = “Daily Exchange Server Report – $now”
$attachment = “C:\scripts\Oakwood Exchange Server Health.html”
$smtpserver = “smtp.yourdomain.com”
####################################
$message = new-object System.Net.Mail.MailMessage
$message.From = $fromaddress
$message.To.Add($toaddress)
$message.IsBodyHtml = $True
$message.Subject = $Subject
$attach = new-object Net.Mail.Attachment($attachment)
$message.Attachments.Add($attach)
$message.body = $body
$smtp = new-object Net.Mail.SmtpClient($smtpserver)
$smtp.Send($message)
I figured it out.
I created a batch file and input:
c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -command C:\Scripts\Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
All working now
Thanks Paul!!!
Great script! I’ve been using it for years on Exchange 2016. Any tips for getting this to work in Windows Server 2016 task scheduler for Exchange 2016?
The Real Person!
The Real Person!
I don’t have any WS2016 servers to test it on right now I’m afraid.
Hi All,
I have other DAG Servers which shows Green and Healthy for DB Copy Suspended DB Copy Failed DB Initializing DB Disconnected DB Log Copy Keeping Up DB Log Replay Keeping Up
However, I have one Server that shows N/A but the Cluster Service Replay Service Active Manager Tasks RPC Listener TCP Listener Server Locator Service DAG Members UpCluster Network Quorum Group have passed.
Does anyone know why It’s not checking DB Copy Suspended and etc and outputting N/A?
Thanks!
The Real Person!
The Real Person!
Some of the tests are n/a when the mailbox server has no active mailbox database copies on it. Basically the Test-ReplicationHealth cmdlet is what is returning those results, and if it doesn’t return a result for one of the items, the script lists it as “n/a” for “not applicable”.
it is not working for exchange 2016.
This script does not find the DAG health summary for exchange 2016 and IP less DAG
Thanks for this cool script Paul. Appying this to EXC2016 and its working . I set up 2 seperate task schedules for this. One runs at 7am daily and sends a report. Then I have a seperate one that runs every 30 minute and will only send an alert if something is amiss.
The issue I am having is that I am getting email alerts about the reply queue being 9 or 12. Is there a way tone down the sensitivity of the replay queues so that I would only get notified when its lets say over 100? Thanks!
The Real Person!
The Real Person!
Yes, you can configure that threshold in the script.
Can you guide to where?
The Real Person!
The Real Person!
Edit the file, scroll down until you find the variables.
Love this script and would like to include a disk space check as well. Probably like most people, we use Volume Mount Points for each DB and LOG directory. Most monitoring tools are not able to check disk space on these, so I using the below in another script.
Any suggestions?
$TotalGB = @{Name=”Capacity(GB)”;expression={[math]::round(($_.Capacity/ 1073741824),2)}}
$FreeGB = @{Name=”FreeSpace(GB)”;expression={[math]::round(($_.FreeSpace / 1073741824),2)}}
$FreePerc = @{Name=”Free(%)”;expression={[math]::round(((($_.FreeSpace / 1073741824)/($_.Capacity / 1073741824)) * 100),0)}}
function get-mountpoints {
$volumes = Get-WmiObject -computer win32_volume | Where-object {$_.DriveLetter -eq $null}
$volumes | Select SystemName, Label, $TotalGB, $FreeGB, $FreePerc | Format-Table -AutoSize
}
#$servers = (Get-Content .\servers.txt)
#foreach ($server in $servers){
get-mountpoints
#}
Hi Paul,
Getting this error on our production Exchange 2016 servers when running the script
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 36
Server version: Exchange 2016
Roles: Mailbox
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 0
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: [Microsoft.Mapi.MapiExceptionSendAsDenied]: MapiExceptionSendAsDenied: Unable to submit message. (hr=0x80070005, ec=1244)
Diagnostic context:
Lid: 40487 EMSMDBMT.EcDoRpcExt2 called [length=46]
Lid: 56871 EMSMDBMT.EcDoRpcExt2 returned [ec=0x0][length=400][latency=15]
Lid: 52176 ClientVersion: 15.1.1261.39
Lid: 50032 ServerVersion: 15.1.1261.39
Lid: 35180
Lid: 23226 — ROP Parse Start —
Lid: 27962 ROP: ropSubmitMessage [50]
Lid: 17082 ROP Error: 0x4DC
Lid: 27745
Lid: 21921 StoreEc: 0x4DC
Lid: 27962 ROP: ropExtendedError [250]
Lid: 1494 —- Remote Context Beg —-
Seems to be related to the issue you mentioned for Exchange 2013 which I know was fixed. running the script from the local Exchange server against the local Exchange server works fine.
The Real Person!
The Real Person!
Other people have reported the same error, but I can’t reproduce it so I don’t know why it is happening, sorry.
I’m getting the same message. I’m running this on an Exchange 2016 server that was hardened using CIS for a US government organization.
Hi Paul-
Where does the script get the Exchange server list itself for the Server Health? I have an old server that has been decommissioned it is still looking for and I cant find where it is. Rather than use the ignore text file, I would like to know where it gets the server list from..
Thank you! This is a great script, its part of our reporting every day.
Tom
The Real Person!
The Real Person!
It uses Get-ExchangeServer to retrieve the list of servers for the org. If you run Get-ExchangeServer and you still see your old server, then your old server was not properly decommissioned.
Hi Paul, after running this script & look at the report, most items look good but in DAG Member Health section, both my servers with *FAILED* in Database Availability column. Wondering what does it mean actually?
Can you provide more guidance to me for further troubleshooting?
Thanks in advance for your help & looking forward to your reply soon!
Ditto, i’m wondering what that means. Great script Paul!
Feature Request:
Is it possible to put a quick error alert in the Subject line? For example, anything that is red just filters up a 1 to the subject of the email or 2 or maybe a “# errors”? Love the script!
Thanks.
Gary
Hi paul,
i am not getting report on email. I have base platform on windows server 2012 R2. Please suggest. Thank You.
Regards,
-Mohsin
Hello Paul,
Thank you not only for this script, but for all your posts, information and experience you are sharing with us. you’re a time savior.
I am facing a small problem, when i run the script manually, everything is fine and I receive the email, but when i run it from Task Scheduler, i receive nothing.
I did the same Action and trigger mentioned above, also checked all the comments and errors but nothing helped me.
when i run the task i can see in the history that action and task completed:
– Action completed: Task Scheduler successfully completed task “\Exchange Health Report” , instance “{ID}” , action “powershell.exe” with return code 0.
-Task Completed: Task Scheduler successfully finished “{ID}” instance of the “\Exchange Health Report” task for user “DOMAIN\administrator”.
What do you suggest?
once again, thank you!
It seems to have been a while for a post. I’m recently running the script and kudos on it Paul.
I want to add to show disk space on server drives
Can you help with that?
Regards,
Christopher
Hi Paul,
I am trying to get the script to run in scheduler on a Windows Server 2016 with Exchange 2016 CU7.
When using -Log I can see the script gets stuck at “Loading the Exchange Server PowerShell snapin”.
When I run the script in Powershell ISE it works perfektly.
Any Idea how to get it up and running on a Windows Server 2016
Best regards and thank you 🙂
Hi Paul,
Thanks for the script. We have been using it for a while and its great.
I am having the same problem as Morten while adding 2016 servers.
I noticed that “Get-ExchangeServer $server” in the script was not returning the 2016 servers so i tried adding :
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri “http:///powershell” -Authentication Kerberos
Import-PSSession -Session $Session | Out-Null
But then the “Set-ADServerSettings -ViewEntireForest $true” throws an error
Any ideas would be really appreciated.
Thanks
Hello Paul. Long term reader, first time “caller”. 😉
We’ve been using your script for quite a while now big fans – Love it. We just got through updating to CU 19 along with 4.7.1 and coinciding with that the script no longer identifies the environment’s lag copy instances and so warnings are generated for the Replay Queues. We’ve confirmed that the lag copy configuration settings remained in tact. We checked and did not see where CU 19 for Exchange 2013 changed lag copy behavior.
Any thoughts on what may be occurring?
Thank you.
The Real Person!
The Real Person!
Maybe that CU has introduced a new lag copy state that the script isn’t accounting for. I don’t have any 2013 servers in my lab to test though. If you have a look at the parts of the script code that deal with lagged copy status you might be able to work out what’s happening.
Thank you for the suggestion Paul.
Hey Paul – Love the script. Really awesome work. Problem I’m having is the mailflow test. It completes successfully on some of the servers but not all. Manually doing a “Test-Mailflow -targetmailboxserver ” works just fine & again it works fine on 3 of the 5. We are in a mixed mode of Exchange 2010 & 2016. The 2010 boxes work great, just 2 of the 5 2016’s don’t. Any ideas of where to begin?
Thanks!!!
The Real Person!
The Real Person!
Any errors when you run the script?
I do get a “Access is denied” when I run the script in report mode. I looked at the administrators group in computer management & they match on all 5 of the servers. I have checked execution policy & all are set to “remote signed”.
The Real Person!
The Real Person!
Where is that error appearing? In the report? In the console output?
It is appearing in the report/log file.
Thanks!!!
Just wanted to take the time to say thank you for time and effort in putting this all together. It’s a great resource.
Great script Paul!
Wanted to know what is the format of the ignorelist.txt?
The Real Person!
The Real Person!
Just a list of names, one per line.
SERVER1
SERVER2
DATABASE1
etc
Paul,
Thank you for the script! I’m having issues with the ignorelist.txt file and have searched all of the comments looking for a solution to no avail. When executing the script I receive the following:
WARNING: The file C:\ExchangeHealth\ignorelist.txt could not be found. No servers, DAGs or databases will be ignored.
I have verified that the file is, in fact, in that exact location. I thought it might be a permissions issue so for testing I gave “everyone” read/write/modify permissions. Still no dice. Any recommendations?
Thanks!
Report shows everything Green on our Exchange 2010 server.
On our Exchange 2016 server it shows a Fail for “Client Access Server Role Services”. I looked in the Windows Services list, and I’m not seeing anything in a stopped state, except for “MS Exchange Notifications Broker”, and “MS Exchange Mailbox Replication”.
Now I’m confused if anything is actually wrong.
The Real Person!
The Real Person!
Run the Test-ServiceHealth cmdlet, it will show you which services it expects to be running.
Thanks. Turned out that it was the Exchange Mailbox Replication service that it was complaining about. Trying to figure out why it won’t start now. At the moment there’s only about 3 people on this new exchange server, and I haven’t noticed any end-user functionality problems with it.
This is exactly what I was looking for. I can’t imagine the time it took to get this to where it is and I think we are ALL very appreciative of this! Thank you for not only creating this script, but also for sharing it as well.
Hi Paul… First of thanks for all your contributions to the Exchange world. You are a life saver to may Exchange admins out there. Coming to my issue. I am running this health report in a mixed 2010 ,2016 environment and only 2010 servers are listed in the html report. If i check the logs , i can see 2016 servers are Tested successfully. Any suggestions?
Paul, ignore my query. I was able to get it working after scheduling Task from the 2016 server instead of running from a 2010 server. Thanks!!
Hi Dilip, I am having problems getting scheduled task to run on my Server 2016 / exchange 2016.
Could you share the settings you use?
Hi Paul – did the test Mailflow command failure on remote servers ever get solved?
Many Thanks
A
I had the same issue. The mail flow part only works fine if Kerberos is configured correctly as Paul said before. You can also ‘fix’ it by commenting line 420. Put a ‘#’ in front of the line. Then it will fall back on the servername (Line 421-424) instead of the URL wich is configured in the virtualdirectory.
Hi Paul,
We have Exchange server 2013 environment across 3 sites.
When we execute script, it gives output for all 3 sites located servers.
We need to execute for each site individually & report should show report for only that site not for all.
What changes need to be done in script & where it need to be done ? Please Suggest.
Paul
I very much like your script, thanks. I am trying to run this script and I get the following warning.
—————————————————————————————————–
WARNING: No snap-ins have been registered for Windows PowerShell version 5.
—————————————————————————————————–
I am running this script on a Windows 10 Machine that has a PSSession to our exchange server.
What am I missing here?
Many thanks
The Real Person!
The Real Person!
The script needs to be run using the Exchange Management Shell, not a remoting session.
Many thanks! How did I overlook that! Sometimes thinking too hard can be your undoing! Thanks for taking the time to respond
Joseph
Ok! Great!
Thanks
Hi Paul,
Great Script! Thanks for sharing and for having your blog that helps a lot newbies like me.
I am having this error when trying to send mails with the report (The Powershell version is 2.0),
can you assist!?
Thanks in advance!
“PS C:\> .\Test-ExchangeServerHealth.ps1
cmdlet Test-ExchangeServerHealth.ps1 at command pipeline position 1
Supply values for the following parameters:
ReportFile: Exchange_Report_24102017.html
SendEmail: $True
C:\Test-ExchangeServerHealth.ps1 : Cannot bind argument to parameter ‘ReportFile’ because it is an empty string.
At line:1 char:32
+ .\Test-ExchangeServerHealth.ps1 <<<<
+ CategoryInfo : InvalidData: (:) [Test-ExchangeServerHealth.ps1], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Test-ExchangeServerHealth.ps1"
Best Regards
Amaro Maguni
If you add the parameter -ReportFile you should define a reportfile, something like:
Test-ExchangeServerHealth.ps1 -ReportFile “HealthReport.html”
The desciption in the help is:
.PARAMETER ReportFile
Allows you to specify a different HTML report file name than the default.
The paramter is optional, you don’t have to use it.
Hi Mark,
I am struggling with the “SendEmail” parameter, not the “Report File”.
If I don’t use the “Send mail” the script works fine!
Thanks for the tip, anyway!
Ah, the error you gave is:
‘Cannot bind argument to parameter ‘ReportFile’ because it is an empty string.’
When you use the e-mail paramter you probably have to define the -ReportFile parameter i think because this is the description: ‘Sends the HTML report’.
.PARAMETER ReportFile
Allows you to specify a different HTML report file name than the default.
.PARAMETER SendEmail
Sends the HTML report via email using the SMTP configuration within the script.
The Real Person!
The Real Person!
It would be helpful to show the exact command you’re running.
I am running “.\Test-ExchangeServerHealth.ps1” command.
with this changes in the script, below:
“[Parameter( Mandatory=$True)]
[string]$ReportFile=”exchangeserverhealth.html”,
[Parameter( Mandatory=$True)]
[switch]$SendEmail,”
The Real Person!
The Real Person!
Setting the parameters to mandatory means you must use those parameters. So if you’re then running the script without parameters, it will throw an error and not run.
I suggest you revert the changes you made to the script code itself, and just run the script with the desired parameters.
cool script, but can you put the
Get-ServerComponentState
in the script?
thx Andi
from Germany
There is another script by Paul for All Mailboxes in the Organization called Get-MailboxReport.ps1. BTW, if you put in the correct parameters the Test-ExchangeServerHealth works beautifully. Just need to be a little bit savvy about your own site and entries.
Hi Paul,
Thanks for this wonderful script!
How can i add mailbox count per server or DB in this report? can you guide?
Thanks!
Rajeesh
Hi Paul,
Thanks for the script, I have been using your script for a while successfuly. Now I am using your script in new organization where I have second DAG member on offsite connected through 100 mb / for both upstream and downstream connection.
I do get yellow flag on “quorum group” and “database availability group”. Though, it appears to be failing over on shutdown and does show OK on get-databasecopystatus * or test. I would presume the remote server reporting as “unable to retrieve uptime” and “could not test service health” is because of slow pipe
Hi Paul,
is it possible to fix the issue on the script with Mail Flow Test failing on remote Exchange 2016 servers?
Thanks
Sir Paul,
Have the script been updated with all the little things you mentioned in the comments, lately?
Thanks.
The Real Person!
The Real Person!
Could you be more specific?
Like DAG Copy Status check and to only email when alerts are detected. Those are old comments and I’m thinking you may already have updated those. Thank you very much for a great script that makes and Exchange Admin’s life easier.
The Real Person!
The Real Person!
Yes, both those features are in the script. You can download the latest version and try it.
Thanks!
I have one other thing that is having issues. I am able to generate an HTML report. However,
#……………………………..
# Modify these Email Settings
#……………………………..
$smtpsettings = @{
To = “administrator@exchangeserverpro.net”
From = “exchangeserver@exchangeserverpro.net”
Subject = “Exchange Server Health Report – $now”
SmtpServer = “smtp.exchangeserverpro.net”
}
Does not seem to work for me. When I use:
param(
[string]$to,
[string]$subject,
[string]$body
)
$smtpServer = removed
$smtpFrom = removed
$smtpTo = removed
$messageSubject = “test”
$messageBody = “test”
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)
I get a test Email. Is there something I’m missing that I am not able to get the report? I am on the highest Server with admin rights.
.\Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
Seems to generate only the report. Scheduled tasks shows completed but does not generate a report or email.
Thanks!!!!!!!!
The Real Person!
The Real Person!
John, run the script in the Exchange Management Shell and look for errors in the output when the mail sends. There’s also a -Log parameter for the script which might capture some useful info.
You can also look at the protocol logs on the SMTP server you’re using to see if/why it’s rejecting the mail.
Hi Paul,
Just come across your script on one of our servers and am running it against a 3 node Exchange 2013 cluster.
In the email I am getting 3 ‘Exchange Server Health’ sections each with all three Servers listed which is confusing. Is this normal?
Thanks
Tony
The Real Person!
The Real Person!
No that’s not normal, but without seeing the report and log file there’s not much else I can say.
Thanks Paul,
Ran the report again this morning and it worked as expected. Didn’t have a log file from previous attempts so couldn’t send you one (ran with -log this morning).
Hi Paul,
I have run the script, and it’s running well, But I am not getting output on mail.
Could you please send me the correct script with required change.
HI Paul,
My system environment is in Chinese version, running script error
Add-Member : Cannot bind argument to parameter ‘Name’ because it is null.
At D:\Test-ExchangeServerHealth\Test-ExchangeServerHealth.ps1:893 char:75
+ $serverObj | Add-Member NoteProperty -Name <<<< $serverinfoservices -Value $svchealth -Force
+ CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCommand
Hi Paul
Add-Member : 无法将参数绑定到参数“Name”,因为该参数是空值。
所在位置 D:\Test-ExchangeServerHealth\Test-ExchangeServerHealth12.ps1:893 字符: 75
+ $serverObj | Add-Member NoteProperty -Name <<<< $serverinfoservices -Value $svchealth -Force
+ CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCommand
if ($Log) {Write-Logfile “$serverinfoservices status is $svchealth”}
$serverObj | Add-Member NoteProperty -Name $serverinfoservices -Value $svchealth -Force
Hello Paul,
Did you get a chance to look the test-mailflow error what i pasted in detail, can you suggest what best can be done here.
The Real Person!
The Real Person!
The error doesn’t occur in my test environment, so there’s not much I can do to troubleshoot it. I suggest you try manually running the Test-Mailflow command and see if that reveals any hints for you.
Paul,
i receive the same error. Some short investigation tells me this:
The script does this:
Connect-ExchangeServer -auto -AllowClobber
I changed it to connect to ‘Server1’ than i receive a mail flow test failure on ‘Server2’. When i connect to ‘Server2’ i recive a mail flow test failure on ‘Server1’. Not sure wich IP is used to send the e-mail from but it might that it is not possible to send an e-mail between the exchange servers? I will try to invstigate this issue to give some more details.
When i run this manualy, i get ‘Success’ as a result. I run the script from a non exchange server with only the management tools installed.
$url = “http://Server1/powershell”
OR
$url = “http://Server2/powershell”
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $url -ErrorAction STOP
$result = Invoke-Command -Session $session {Test-Mailflow} -ErrorAction STOP
$e15mailflowresult = $result.TestMailflowResult
$e15mailflowresult
—–
When i run this directly on both exchange servers, i get succes as well.
Test-Mailflow -TargetMailboxServer Server1
Test-Mailflow -TargetMailboxServer Server2
Any clues?
Running the Test-ExchangeServerHealth directly on the Exchange servers generates the same error ‘Mail flow test: [Microsoft.Mapi.MapiExceptionSendAsDenied]: MapiExceptionSendAsDenied: Unable to submit message. (hr=0x80070005, ec=1244)’
hello Paul,
We have changed the details suggested by you & I have put my email address in the from field. I am not sure whats wrong with the report or whats mistaken from my end but I do not receive output email
The Real Person!
The Real Person!
Use the -Log parameter to output a log file when the script runs. The log file might have some clues why the SMTP send at the end is not working.
Hello Paul,
While running the script getting the below error during the Test- Mail flow , is any can be done to get rid of this issue and get a successful result.
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 186
Server version: Exchange 2013
Roles: Mailbox, ClientAccess
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 0
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: [Microsoft.Mapi.MapiExceptionSendAsDenied]: MapiExceptionSendAsDenied: Unable to submit message. (hr=0x8
0070005, ec=1244)
Diagnostic context:
Lid: 40487 EMSMDBMT.EcDoRpcExt2 called [length=46]
Lid: 56871 EMSMDBMT.EcDoRpcExt2 returned [ec=0x0][length=304][latency=296]
Lid: 52176 ClientVersion: 15.0.1320.4
Lid: 50032 ServerVersion: 15.0.1320.4
Lid: 23226 — ROP Parse Start —
Lid: 27962 ROP: ropSubmitMessage [50]
Lid: 17082 ROP Error: 0x4DC
Lid: 27745
Lid: 21921 StoreEc: 0x4DC
Lid: 27962 ROP: ropExtendedError [250]
Lid: 1494 —- Remote Context Beg —-
Lid: 41788
Lid: 44092
Lid: 41232
Lid: 60208
Lid: 37136
Lid: 34608
Lid: 55056
Lid: 42768
Lid: 56112
Lid: 33016 StoreEc: 0x4DC
Lid: 63016 dwParam: 0x32
Lid: 39640 StoreEc: 0x4DC
Lid: 10786 dwParam: 0x0 Msg: 15.00.1320.000:EXCSRV13PRDN01
Lid: 1750 —- Remote Context End —-
Lid: 26849
Lid: 21817 ROP Failure: 0x4DC
Lid: 60547 StoreEc: 0x4DC
Lid: 21966
Lid: 30158 StoreEc: 0x4DC
—— Finishing
Done.
have you had any success with this?
Hello Paul,
Thank you for the excellent script
I am adding the list of servers which should be excluded in the health checks in ignorelist.txt
However it is not working
The script is modified
ignorelistfile = “$myDir\ignorelist.txt”
It is replaced with
gnorelistfile = “e:\scripts\ignorelist.txt”
Yes, running the V1.16, 13/04/2017. We did find recently that our AD replication was slow and causing trouble with our lagged copies but that has been resolved. In about 10-12 days we’ll be patching and rebooting again so that may change the situation. I did sort of fix the Preference column but the rest still eludes me.
Thanks!
Hi Paul, is there a way to check the health of our lagged copies, short of forcing them to play down the logs?
The Real Person!
The Real Person!
Exchange checks that for you. You can see their health in the Get-MailboxDatabaseCopyStatus output.
Hi Paul, your generous postings have helped us many times over the last couple years, thank you! A recent issue I have noticed since we installed CU5 on our E2016 on premise is this health report output has changed for us. It could be our environment but I thought I’d mention it although I am attempting some modifications to the script as an exercise in learning powershell better. Under the health summary section, the Preferences column is empty and the Lagged Queues column shows 0 instead of 1 for us. Likewise under Health Details the Activation Preference has no entries, and under Member Health the Server column is now empty.
It seems to be having trouble with lagged copies now, but again it may be just us and not the script. It shows as:
Database Availability Group Health Check Summary
The following DAG errors and warnings were detected.
• DB101 – healthy copy/replay queue count is 3 (of 4 )
• DB102 – healthy copy/replay queue count is 3 (of 4 )
• DB103 – healthy copy/replay queue count is 3 (of 4 )
• DB104 – healthy copy/replay queue count is 3 (of 4 )
etc.
Thanks again for such a helpful blog!
Best Regards,
David
The Real Person!
The Real Person!
Have you downloaded the latest version of the script?
I’m not sure if this has already been commented on in the previous 800+ posts but I was having issue with the script executing via Scheduled Task. I believe it was due to the execution policy on the local machine, even though I have “Run with the highest privileges” checked and running with domain admin/local admin credentials.
Try running the argument with the following switches:
-noprofile -executionpolicy bypass -file C:\LocationsOfFileTest-ExchangeServerHealth.ps1 -Log -SendEmail
Works fine for me now.
Hope that helps anyone experiencing the same issue.
Hi Paul
Thanks for this useful script
We were experiencing Event ID 9045 “Service MSExchangeMailboxAssistants. The assistant Junk E-mail Options Assistant stopped processing database DAG Mailbox Database 1 (855a438f-30d4-4615-b074-3e1e7a669935) because the database is in an unhealthy state.” errors every 15 mins – when checking the DAG it appeared to be healthy however and test replication health returned success for both mail nodes. I ran your script and whilst it did error in a couple of places it seemed to test everything ok – the next morning however users were met with a message ‘your administrator has made changes that require you to restart outlook’
I don’t think the maibox moved between DAG/nodes or anything – have you seen this happen before?
Many thanks in advance, Jason
The Real Person!
The Real Person!
Database replication might be healthy but the database itself might have some problems. You should open a support case with Microsoft for advice n that one, or if it’s confined to a single database you could also create a new DB and evacuate that suspect DB and get rid of it.
The restart message in Outlook is possibly due to a DB failover between DAG notes. If any of your CAS namespaces or other vdir settings are inconsistent then clients might see those types of messages. Run https://exchangeanalyzer.com/ if you want to quickly check for obvious issues.
Hi Paul
Many thanks for taking the time to reply. I’ll check this out
Regards
Jason
I run this script in both my Exchange 2010 environment and my 2016 environment.
I am seeing errors in my 2016 environment:
Starting a command on the remote server failed with the following error message: The I/O operation has been aborted because of either a threat exit or an application request.
Also:
The request fro the WIndows Remote Shell with Shell ID *** failed because the shell was not found on the server. Possible causes are: the specified ShellID is inccorect or the shell no longer exists on the server.
Hello Paul
we use your script exchange-server-health. A great Code and great tool.
we use it with -SendEMail -AlertsOnly Parameter.
Is it posible that change the warning limits, because now we become to many Mail with warnings?
Example – today:
yellow Healthy Queues Unhealthy Queues 1
and
yellow Replay Queue = 21
I think thats to small limit für 2 Exchange with 1000 Users
great tool – thanks to all
The Real Person!
The Real Person!
You can customize those alert thresholds in the script.
Is there is a way to include the following information to the part of the report.
Mailbox server hosting active copy
Database Size and whitespace
Mailbox Count on each database
Mailbox Average Sizes
Database and log disk free space
Last Full Backup
Mailbox database Queue status
Mail Queue status on HUB server
Hi Paul,
is there a way to convert the report to pdf? and then mail it out as an attachment?
Thanks.
The Real Person!
The Real Person!
I haven’t looked into it. Perhaps there is some PowerShell modules that can handle that. Sounds like an interesting customization for you to try out, but I won’t be adding it myself.
Hi Paul,
I seem to get the below error but am not sure how I can resolve this:
Mail flow test: WARNING: Connecting to remote server uk.olayan.net failed with the following error message : WinRM cannot process the
request. The following error occurred while using Kerberos authentication: Cannot find the computer uk.xxxx.net.
Verify that the computer exists on the network and that the name provided is spelled correctly. For more information,
see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:\support\ExchangeServerHealth\Test-ExchangeServerHealth.ps1:452 char:22
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
Thanks for a great script Paul,
Have you considered adding a check for inactive component states?
I ended up running a modified version of Mr Loeber’s Get-Exchange2013ComponentStateHistory script alongside your health check script since my HLB didnt pick up on the inactive states.
Paul,
Can you implement what Rosario did in future releases?
– local Drives: Capacity, Used, Free Space
– Mount Points: our DBs are directly attached via SAN now, so again, MountPoint Name, Capacity, Used, Free Space
– DB statistics: DB Size, Number of Mailboxes, Mailbox Average Size, WhiteSpace in DB, Date of last FullBackup
Found on your site about Stevie script
http://www.stevieg.org/2011/06/exchange-environment-report/
Thx
Paul,
Same here, if possible can you please add?
Especially the DB size can be useful as DAG will only failover if the DB is less than 1TB in Standard edition.
Thanks for considering Paul.
Hi Paul,
It is nice and healthful script. Many of the interested information is there. What I would add is: DB backup status (warning if the backup is older than 7 days), certificate expiration (warning if they expired or going to expire in X days), disk space issue (specially useful for LOG partion). Also, it would be nice to be able to exclude one or more counters from the report (adding “#” ..)
Thank you.
Hi
ignorelist.txt is being ignored for me, it is stored in the same folder as the PS script
Any ideas ?
The Real Person!
The Real Person!
What do you see in the console or in the log when you run the script?
What does the result total queue mean? I have 598
The Real Person!
The Real Person!
I don’t have a column named total queue in my report. Which section are you seeing that in? Are you using the latest script?
I should be, script Updated 4/13/2017
Here’s a part of what I see when I run the powershell script:
DNS Check: Pass
Ping Check: Pass
Uptime: 2717
Server version: Exchange 2010
Roles: ClientAccess, HubTrasport
Client Access Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total queue: 601 (This number is in red)
Am I using the wrong one?
The Real Person!
The Real Person!
No it just wasn’t clear that you were referring to the console output instead of the HTML report.
Total queue is the number of messages in your transport queues. You can investigate that further by running the Get-Queue cmdlet.
Paul,
I just wanted to take a moment to say thanks for your work on this. Just brilliant! Works like a charm. Keep up the great work.
Hi Paul,
I would like to run the health check on Edge Server alone. I have tried removing if from the line
#Skipping Edge Transports for the general health check, as firewalls usually get
#in the way. If you want to include them, remove this If.
if ($IsEdge -ne $true)
and also tried by changing the value to if ($IsEdge -ne $true) to if ($IsEdge -eq $true) but didn’t work.
Coud you please help me with it?
The Real Person!
The Real Person!
I haven’t written any test logic for Edge Transport servers, so I wouldn’t expect that to work at all.
Hi Paul.
Can anyone help with this issue
Mail flow test: WARNING: Connecting to remote server mbox-2 failed with the following error message : The WinRM client c
annot process
the request. It cannot determine the content type of the HTTP response from the destination computer. The content type
is absent or invalid. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:\Scripts\Test-ExchangeServerHealth\Test-ExchangeServerHealth.ps1:450 char:22
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
Thank you
The Real Person!
The Real Person!
Check whether you can create a PS remote session to that Exchange server manually. Might be something wrong with the WinRM config.
Paul, I am getting the error as below:
—— Checking EXC02
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 105
Server version: Exchange 2016
Roles: Mailbox
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 0
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: WARNING: Connecting to remote server mail.cam.net.in failed with the following error message : WinRM cannot process the request. The following error occurred while using Kerberos authentication: Cannot find the computer mail.cam.net.in. Verify that the computer exists on the network and that the name provided is spelled correctly. For more information, see the abo
ut_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the argument, and then try running the command again.
At C:\Users\admin\Downloads\Test-ExchangeServerHealth.ps1:450 char:22
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
—— Checking EXC50
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 1231
Server version: Exchange 2016
Roles: Mailbox
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 0
Mailbox databases mounted: Pass
Mail flow test: No active mailbox databases
—— Finishing
Done.
The Real Person!
The Real Person!
That error occurs when the PowerShell virtual directory has been configure with an alias for the URL.
Mail flow test: *FAILURE*
Only Exchange Server 1 is giving this error. I am checking queue viewer ;
Last Error: 421 4.4.2 Connection dropped due to ConnectionReset
I disabled Windows firewall and psychical firewall for exchange ip address. but problem still is continuing
Malware agent status disable.
can you help me ? Thanks.
power shell script output to HTM or CSV
how we can add output method to the script
The Real Person!
The Real Person!
The script already supports outputting to a HTML file.
Output to CSV file is not included in the script. The structure of the data is not suitable for CSV format. If you need CSV output, you’ll need to customize the script to meet your requirements.
I’ve just tried to run via scheduled task to send an email and no joy – ive even changed to run via the exchange management shell and then does send email but then just the headers and nothing else…
To save me any time and changing all the code – is there a way we can just make the script to be persistent to just always send the email to the smtp settings?
The Real Person!
The Real Person!
You can change the code around the Send-MailMessage commands so that it always sends the email, but it doesn’t sound like that will solve your problem. You can also output the report to HTML file to see whether the problem is with the data collection or the sending of the email itself. If the HTML report looks fine, then it’s an SMTP problem of some kind. If the HTML report is broken, then something else is wrong. There’s also the -Log switch which might help you with visibility into what’s going wrong.
Mohammad Ajan
how we can get output of power shell script to HTM,CSV we want to click on this file and give me result in htm,or CSV how we can include htm output
plese write here the method of output in the script
When I run the script (-sendemail), it does not output the DAG HEALTH SUMMARY and DAG HEALTH DETAILS, it only output Server Health check and DAG health member checks.
The Real Person!
The Real Person!
Run the script in your Exchange Management Shell with the -Log parameter. Watch for errors on screen, or review the log file to see if there’s any issues. Make sure you haven’t added the DAG name to the ignorelist.txt file.
Pingback: Health Checking / Monitoring Exchange Server 2013/2016 – A random blog from a sysadmin
Version 1.15
Line 424 references variable $testresult that does not exist anywhere else in the script… ??
The Real Person!
The Real Person!
Thanks. I’ve added it to my issues list in GitHub.
Sending email.
Send-MailMessage : Cannot validate argument on parameter ‘To’. The argument is null or empty. Supply an argument that i
s not null or empty and then try the command again.
At H:\Test-ExchangeServerHealth.ps1:2103 char:20
+ Send-MailMessage <<<< @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF
8)
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
The Real Person!
The Real Person!
Looks like you haven’t set the SMTP settings in the script.
When script is run it show below error
Sending email.
Send-MailMessage : Cannot validate argument on parameter ‘To’. The argument is null or empty. Supply an argument that i
s not null or empty and then try the command again.
At H:\Test-ExchangeServerHealth.ps1:2103 char:20
+ Send-MailMessage <<<< @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF
8)
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
While executing script in our environment it fails with below errors.
[PS] C:\script>.\Test-ExchangeServerHealth.ps1
Initializing…
WARNING: The file C:\script\ignorelist.txt could not be found. No servers, DAGs or databases will be ignored.
—— Checking EXSVR16A
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 359
Server version: Exchange 2016
Roles: Mailbox
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 1
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argu
ment that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:\script\Test-ExchangeServerHealth.ps1:426 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
—— Checking EXSVR16B
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 359
Server version: Exchange 2016
Roles: Mailbox
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 4
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argu
ment that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:\script\Test-ExchangeServerHealth.ps1:426 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
—— Finishing
Done.
We are using Exchange 2016
The Real Person!
The Real Person!
See comment above. I’ll try and fix this as it seems to be impacting so many people.
We had the same error. It turned out that we had inadvertently changed our Powershell virtual directory URLs to use https and our load balancer name, so this script was failing to create a remote powershell session. We reverted the URLs back to the defaults (http://servername.domain.tld/powershell) and the error is gone.
I am using Exchange 2013 and have 4 mailbox servers in a DAG – three in primary site and one in DR site. I tried running the script in the three mailbox servers in the primary site and notice that the mail flow test always fails only in the server running the script while the mail flow test for other servers are OK. The error is shown below.
**** Error begins ****
Mail flow test: WARNING: Connecting to remote server tvm-exdb03 failed with the following error message : The WinRM client cannot process the request. It cannot determine the content type of the HTTP response from the destination computer. The content type is absent or invalid. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Supply a non-null argument and try the command again.
At C:\work\Test-ExchangeServerHealth.ps1:426 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
**** Error ends ****
Please kindly help.
Exchange: 2013
Windows: 2012 Standard
Powershell: 3.0
BTW, I think this script is great and very useful for doing health check of Exchange environment.
Thanks and regards,
Joseph Liu
The Real Person!
The Real Person!
Seems a lot of people get that error, but I don’t have an immediate solution for you. I will try and fix it, since it seems to be such a widespread problem.
I spoke too quickly. Even though I got the script to run from the task scheduler and send email, the main data line in the report was blank. The log file reports “No DAGs found.”
So I revised my batch file to include the server parameter:
powershell.exe -PSConsoleFile “C:\Program Files\Microsoft\Exchange Server\V14\Bin\ExShell.psc1” -command “C:\scripts\Test-ExchangeServerHealth.ps1 -server myexchgsrv.mydomain.local -log -ReportMode -SendEmail”
But that produces the produces a log file that terminates with the line, “could not find the server myexchgsrv.mydomain.local
Both versions of the batch file work fine from the command line. Any idea of what could be causing the server to be unfindable when running from task scheduler?
Answer at https://social.technet.microsoft.com/Forums/scriptcenter/en-US/d5734b40-8bca-4664-9a43-5163d63d6fde/what-can-cause-a-script-launched-from-explorer-to-fail-when-launched-from-task-scheduler?forum=ITCG#ab976705-c9f9-42df-8a42-b515b2fc711c
Hi Paul, Thanks for your script but I am getting below error and mail flow Test is failing on one server “Jet-MBX1” only regularly with script whereas if I Test -mailflow on server manually it shows result as “success” so script is showing False result.
How can we correct this, Please suggest. My email address is as shown below.
Prasad.jahagirdar81@gmail.com
mail flow test: WARNING: Connecting to remote server jet-mbx2 failed with the following error message : The WinRM client
cannot proces
the request. It cannot determine the content type of the HTTP response from the destination computer. The content type
is absent or invalid. For more information, see the about_Remote_Troubleshooting Help topic.
ARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
ot null or empty, and then try the command again.
The WinRM client cannot proces the request. It cannot determine the content type of the HTTP response from the destination computer
Thank you Paul, Great work…
I would like to schedule this report on daily basis How can i write ? Can you please help on this.
Thank you
Thank you Paul. great script.
we have ben running this since few months and since yesterday we are getting error
Could not test service health. : System.Management.Automation.RemoteException: Couldn’t get information about the Excha
nge services using Windows Management Instrumentation (WMI) due to error: WMI exception occurred on server Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
trying to figure it out but no clue.
The Real Person!
The Real Person!
Anything particular about that server that might be relevant?
Now we sre getting access denied for all servers in the domain.
$unhealthyindexes = @($copies | Where-Object { ($_.”Content Index” -ne “Healthy” -and $_.”Content Index” -ne “Disabled” -or $_.”Content Index” -ne “AutoSuspended”) }).Count
Ignore autosuspended for $unhealthyindexes since those are no unhealthy.. they are autosuspended 🙂
-and not -or.. argh! sorry
$unhealthyindexes = @($copies | Where-Object { ($_.”Content Index” -ne “Healthy” -and $_.”Content Index” -ne “Disabled” -and $_.”Content Index” -ne “AutoSuspended”) }).Count
I confirm, I also modified the script to ignore the AutoSuspended. I’ve added it to the Git but Paul Cunningham has not yet accepted the Pull. https://github.com/cunninghamp/Test-ExchangeServerHealth.ps1/commit/576d5d41f8e7b32225f079f5df155ca8ef41be6b
I have added a control of the space of the partitions of the servers as well as the location of the bases. I also added a ratio between the size of the base and the free space of it in order not to save space for nothing (if there is backup) : https://github.com/aikiox/Test-ExchangeServerHealth.ps1/tree/patch-1
Thanks for such a good Script.
We were trying to customize it to our requirement so was trying to understand the script, we are not a full time programmer.
Could you please explain how the following commands works, because these variables were not declared in Param, please help us understand.
Function New-DAGMemberHTMLTableCell()
{
param( $lineitem ) –> What is the value of this, what it does?
$htmltablecell = $null
switch ($($line.”$lineitem”)) –> What is $($line.”$lineitem”)? please help me understand?
{
$null { $htmltablecell = “n/a” }
“Passed” { $htmltablecell = “$($line.”$lineitem”)” }
default { $htmltablecell = “$($line.”$lineitem”)” }
}
return $htmltablecell
}
Like wise,
param( $logentry )
param ( $e15cas )
param ( $e15cas )
param ( $e15mailboxserver )
param ( $e14mailboxserver )
None of the above are declared in Param command, but still it works, how?
The Real Person!
The Real Person!
Short answer, variables don’t need to be declared in param. Param is for script/function parameters.
Hello,
I made a pull request on the Git to integrate the basic notion laggued with the status “AutoSuspended”. From the CU4, this new status allows to automatically pause the lagged bases to avoid overconsumption of the bandwidth. I opened a ticket at Microsoft to learn more about this status that is not documented. Here is the answer :
I confirm that the Autosuspend of the passive bases lag is a normal behavior.
We reproduce it and I have identified the change in the voluntary code.
I guess the reason could be a gain in terms of CPU.
In spec it appears that this change was made in order to reduce the consumed bandwidth to index the active database.
I recommend you to keep it in autosuspend but you have the command if you want to reactivate the index as in CU1.
Here is the command to disable this status:
New-SettingOverride -Name DisableSkipLagCopy -Component Search -Section SkipLagCopy -Parameters @(“Enabled=false”) -Reason “Disable SkipLagCopy”
The parameter is not taken into account dynamically, it is necessary to plan a reboot.
After restarting, probably a reseed is necessary because the index is not up to date: Update-MailboxDatabaseCopy nomdelabase -CatalogOnly
We have reproduced and checked on our DAG this procedure successfully to reactivate the index.
In the Pull Request, I also added the exact version of the Exchange. It’s always nice to know which CU we have on which server.
I also put the part “Queue” in function to try repeatedly if one is above the threshold. This is to avoid having alerts when we have just received an enormous amount of email at once.
Romain
Hello Paul,
I’m getting the below error when I run the script, Kindly help on this.
WARNING: Connecting to remote server failed with the following error message : WinRM cannot
process the
request. The following error occurred while using Kerberos authentication: Cannot find the computer . Verify
that the computer exists on the network and that the name provided is spelled correctly. For more information, see the
about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:\temp\Test-ExchangeServerHealth.ps1:426 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommandFail
Hi All
Can we add oldest log files (Text files) info (Time stamp) with number of days old to the script as another column? Can you please help?
Thanks
I’m another user who simply cannot get your script to run as a scheduled task. I’ve followed your instructions to the letter and experimented with modifications. Nothing works — the task scheduler just shows it running endlessly. The history hangs on event 110, “task triggered by user.” It stays there until you manually terminate.
This command works perfectly in an administrative CMD shell:
powershell.exe -command “C:\scripts\Test-ExchangeServerHealth.ps1 -Server myserver.mydomain.local -ReportMode -SendEmail”
When you try to set it up as a scheduled task as follows:
Run whether user is logged in or not
Do not store password
Run with highest privileges
Action: start a program
Program/script: powershell.exe
Add arguments: -command “C:\scripts\Test-ExchangeServerHealth.ps1 -Server myexchange.mydomain.local -log -ReportMode -SendEmail”
Allow task to be run on demand
Stop the task if it runs longer than 1 hour
If the running task does not end when requested, force it to stop
it simply will not run. Can you tell me what I’m doing wrong? I don’t have any problem running a WSUS maintenance script in the same fashion.
The Real Person!
The Real Person!
Use -Log and see if the log gives you any clues.
But I would also suggest that “Do not store password” is going to cause a problem.
The log just says
17 17:03:51 =====================================
01/26/2017 17:03:51 Exchange Server Health Check
01/26/2017 17:03:51 01/26/2017 17:03:51
01/26/2017 17:03:51 =====================================
01/26/2017 17:03:51 Initializing…
01/26/2017 17:03:51 Loading the Exchange Server PowerShell snapin
Is there a way to get task scheduler to use the special Exchange powershell? Or what needs to be added to your script to get the regular powershell to add the Exchange add-in?
The Real Person!
The Real Person!
If you login with the creds that the scheduled task is running as, does the script work?
Yes, in both instances, it’s the domain administrator. Isn’t the problem one of being able to access the Exchange functionality? All sessions are being run on the Exchange server.
Is there something that needs to be in your profile so that the Exchange Server Powershell snapin is already loaded before the script begins executing?
The Real Person!
The Real Person!
The script loads what it needs automatically, unless it can’t (e.g. due to permissions). I haven’t been able to repro your issue. I’d suggest creating a new service account and trying a different set of creds for the scheduled task.
Doesn’t the domain administrator have all of the permissions required? What is different (besides screen output) between running it in an administrative command shell and running it with the same account and full permissions from the task scheduler?
It’s just a standard off-the-shelf Dell server with Server 2012 R2 and Exchange Server 2010 running on it. If you’re curious and would like to examine this mystery firsthand, that can be easily arranged.
The Real Person!
The Real Person!
Depends what you think the “domain administrator” is. Members of Domain Admins or Administrators don’t get any Exchange admin permissions by default. Exchange has its own permissions model.
This is your first mention of trying to run it on Exchange 2010. I’ll test on a 2010 box next chance I get. It should work, but I don’t recall the last time I tried it.
Thanks. If it works, please let me know the permissions that the account you use in task scheduler has. Meanwhile, I’ll continue to experiment on my end with permissions and let you know if I find anything.
JSYK: The domain administrator account that I’m using for both the command line and the scheduled task is also a member of the organization management group for the Exchange server.
The Real Person!
The Real Person!
On an Exchange 2010 server this command is working fine (from cmd.exe and from task scheduler)
powershell.exe -command “. C:\Scripts\ExchangeServerHealth\Test-ExchangeServerHealth.ps1 -Log -SendEmail”
The scheduled task has “Run with highest privileges” ticked per my article above. Without that box being ticked the script stalls on “Loading the Exchange Server PowerShell snapin” in the log file.
Funny … if I modify my path for yours and paste this into an administrative command prompt
powershell.exe -command “. C:\Scripts\Test-ExchangeServerHealth.ps1 -Log -SendEmail”
All it does is display what’s between the quotes on the next line. If I remove the quotes and the period, it runs correctly from the command prompt. But as always happens — when I put a working command line into task scheduler with the highest privileges (as always), all I get is a neverending “running.” Could you please cut and paste what you have in the “program/script” and “add arguments” boxes of your working scheduled task?
The Real Person!
The Real Person!
The program is powershell.exe and the arguments are
-command “. C:\Scripts\ExchangeServerHealth\Test-ExchangeServerHealth.ps1 -Log -SendEmail”
I’ve got Exchange 2010 running on WS2008R2, so if you’re on a different OS maybe there’s a PowerShell version thing that needs a different approach.
Hmmm … this is Exchange 2010 running on WS2012R2. Do you know of anyone successfully scheduling it on a similar platform that you can get the arguments from?
The Real Person!
The Real Person!
Exchange 2010 isn’t supported to run on WS2012R2, so I don’t think you’ll find many people with that scenario.
You could install the management tools on another server or workstation and run the scheduled task from there.
But it executes perfectly from the command line, so it should execute in the task scheduler as well. Regardless of the Exchange version, could you give me the entry in the parameters box in the task scheduler for a Server 2012 machine where scheduling works? And does installing the management tools on a server require installing Exchange Server 2010 as well? The only instructions I can find seem to say so. https://www.petri.com/install-exchange-2010-management-tools-windows-8
The Real Person!
The Real Person!
The scheduled task settings I use are in the blog post above.
The management tools can be installed on a workstation or server without installing the full Exchange server application itself. The tools are a separate role in setup as that blog you link to shows.
Yes, but those scheduled task settings are for WS2008 — they don’t work in WS2012 either as a scheduled task or as a command line. Do you (or anyone else) have the settings for the script working as a scheduled task in WS2012?
The Real Person!
The Real Person!
I’ve given you what works for me with Exchange 2013 running on WS2012R2 (it’s in the blog post) and what works for me with Exchange 2010 running on WS2008R2 (in comments above).
That’s all I’ve got I’m afraid. Looking around on Google there seems to be a variety of ways of “running PS scripts in task scheduler” that might have some version-specific nuances but all I can say is what works for me.
I found a solution:
powershell.exe -PSConsoleFile “C:\Program Files\Microsoft\Exchange Server\V14\Bin\ExShell.psc1” -command “C:\scripts\Test-ExchangeServerHealth.ps1 -log -ReportMode -SendEmail”
I put it in a BAT file, and it executes from task scheduler now. The console file makes all the difference.
Paul,
Great Script. VERY helpful. I do have a question that I am sure shows how much of a noob I am in Powershell. I am trying to figure out a way for the report name to automatically update with the date of the day it is run.
Example: 022617.ESH.html instead of exchangeserverhealth.html
The Real Person!
The Real Person!
There’s a variable in the script that sets the output file name. Just change that to whatever suits your needs.
Paul consulta en mi reporte que me genera , en la columna UPTime me sale este mensaje: Unable to retrieve uptime y se sombrea de amarillo, esto es normal o a que se debe
Hi Paul, Awesome script, I use it to check the health of Exchange 2010 each mornning. I am experiencing a strange issue. I have 2 sites with 2 mailbox servers in each site, the main site has 3 client access\hub transport servers and the other site has 2 client access\hub transport servers. When I run the script as a scheduled task from the main site the report emails however 1 of the CA\HUB servers has the message “Unable to retrive uptime” for uptime hours & “could not test service health” for CAS, HUB, MB & UM. DNS, Ping & Transport queue pass. This only happens on one of the CAS servers on that subnet but I can run the test-servicehealth manually from the EMS.
When I run the script from a schedule task from the secondary site 2 of the CAS\HUB servers in the main site have the same problem.
Really hope you can help with this.
Cheers
Martin
Paul, I reviewed the comments for this script spanning the last 4 years. I’m impressed with your on-going support. No problems to report, just wanted to drop a line to commend your efforts.
Paul,
I commend you on all of the work and scripts you have for Exchange. I have used your resources countless times.
I have recently implemented Exchange 2013 coexistence with Exchange 2010. No mailboxes have been moved to 2013 as of yet.
When I run this script from 2013MB5 , I get three failures on mailboxes.
Exchange 2010MB1, Exch2010MB2 and Exch2013MB5 – access denied
12/12/2016 09:50:30 Initializing…
12/12/2016 09:50:31 Loading the Exchange Server PowerShell snapin
12/12/2016 09:50:37 Setting scope to entire forest
12/12/2016 09:50:46 You have specified a single server to check
12/12/2016 09:50:49 Beginning the server health checks
12/12/2016 09:50:49 —— Checking Exch2010MB1
12/12/2016 09:50:50 Checking DNS
12/12/2016 09:50:51 DNS check passed
12/12/2016 09:50:51 Checking ping
12/12/2016 09:50:56 Ping test passed
12/12/2016 09:50:56 Checking uptime
12/12/2016 09:50:57 Uptime is 858 hours
12/12/2016 09:50:57 Server is running Exchange 2010
12/12/2016 09:50:57 Server roles: Mailbox
12/12/2016 09:50:57 Checking service health
12/12/2016 09:51:04 Mailbox Server Role Services status is Pass
12/12/2016 09:51:04 Checking Mailbox Server
12/12/2016 09:51:09 Checking public folder database
12/12/2016 09:51:09 Public folder database status is Pass
12/12/2016 09:51:09 Checking mailbox databases
12/12/2016 09:51:09 Mailbox database status is Pass
12/12/2016 09:51:09 Checking MAPI connectivity
12/12/2016 09:51:16 MAPI connectivity status is Success
12/12/2016 09:51:16 Checking mail flow
12/12/2016 09:51:17 Processing data from remote server Exch2010MB1 failed with the following error message: Access is denied. For more information, see the about_Remote_Troubleshooting Help topic.
12/12/2016 09:51:17 Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
12/12/2016 09:51:17 Mail flow status is Fail
Exch2010MB3 and Exch2010MB4 pass with no errors
If I run the script from a 2010MB, I get no errors and all tests pass.
Any suggestions?
The Real Person!
The Real Person!
The mail flow test tries to do a remoting session to the other servers as a hacky workaround for changes in the Test-MailFlow cmdlet when 2013 was released. It throws errors if the remoting session can’t be established. It’s not a great way of doing it, unfortunately.
Is there a specific way to setup the ignore list? No matter what I try, it never ignores the servers or DB’s I put in it. I have each one on a single line, no header, no quotes, but I’ve tried it every other way as well and still the report comes with every server that it shouldn’t be checking.
I currently have 58 servers, 22 of which are 2010 in coexistance with Exchange 2013. I’m on the final stages of the 2010 before I decommission it so I don’t want these to clutter the report, but for the life of me I can’t get the script to ignore these.
Any suggestions?
Thanks!
NM, think I figured it out. It was ignoring the servers, but I didn’t put in the DB’s and DAG’s for all of those servers.
Now I am getting only the 2013 servers as I wanted.
Cheers!
Now if I can just figure out how to get the scheduled task to work.
Hello Paul –
Thanks for the great scripts, we’ve been using the DAG health & backup status reports for several years.
In case anybody’s wondering about the Kerberos error some correspondents have reported…
The same thing cropped up in our environment with newly deployed Exchange 2016 servers and the latest version of Test-ExchangeServerHealth.ps1
Mail flow test: WARNING: Connecting to remote server mail.DOMAIN.COM failed with the following error message : WinRM cannot process the request. The following error occurred while using Kerberos authentication: Cannot find the computer mail.DOMAIN.COM. Verify that the computer exists on the network and that the name provided is spelled correctly…
During the initial server configuration we had set the virtual directories for Powershell on each Exchange server to use the load-balanced name…
Set-PowerShellVirtualDirectory “$HostNamePowerShell (Default Web Site)” -InternalUrl “https://mail.DOMAIN.COM/Powershell”
But this isn’t going to work here, so a crude workaround is to #REM out the IF construct around the line…
$url = “http://$e15mailboxserver/powershell”
i.e. forcing the script to use a URL incorporating the Exchange server name each time in the New-PSSession command
Thanks again
Test-mailflow always failed on mbx server hold passive copy DB. Any idea? Error message is same as what mentioned above.
“WinRM…”
I tried the edit recommended by Stubbo but I’m having the same issue. Exchange 2016 with load balancer…
Hi Paul,
Love your script – I am new to powershells and this is wow.
I follow the comments and having a problem running this scripts from the task scheduler.
Its status is Running but its stays on like that until I end the task.
my action is: start a program
Program/script : C:WindowsSystem32WindowsPowerShellv1.0powershell.exe
arguments : -ExecutionPolicy Bypass -NonInteractive -Command “& ‘C:PowershellscriptExchangeHealthTest-ExchangeServerHealth.ps1’ -ReportMode -SendEmail”
If anyone made this work it would be great to know how
Hi Paul,
Could you help me on my request.
” have ran this report in my lab everything is perfect very perfect. but i personally feel if you help me to include Diskspace report that would be really helpful for us to understand the Logs drive space and DB drive space”
sorry, it is fixed
Hi Paul,
thx 4 ur script, but i have one small problem. why not send one email ro my mailbox even i edit relative settings for SMTP?
Hi Paul,
i have ran this report in my lab everything is perfect very perfect. but i personally feel if you help me to include Diskspace report that would be really helpful for us to understand the Logs drive space and DB drive space.
Dear Paul ,
when i try to execute your script its working but with the below error
Script : The term ‘Script’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
At C:scriptsTest-ExchangeServerHealth.ps1:1 char:1
+ Script Içerigimiz:
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (Script:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Initializing…
Creating a new session for implicit remoting of “Get-ADServerSettings” command…
The file C:ScriptsExchangeServerHealthignorelist.txt could not be found. No servers will be ignored.
The Real Person!
The Real Person!
Have you modified the script?
Hello Paul,
Hope you are doing well and thanks for the great work.
I would like to know the syntax or how to create the ignorelist? when runing this script and get-daghealth also.
Thanks again
The Real Person!
The Real Person!
Just one item per line, e.g….
DATABASE01
DATABASE02
SERVER01
Thanks for a great tool Paul.
Our enviroment has Trend Micro ScanMail installed on the Exchange servers. As a result, there is an unmounted database on each server called “EUQ_ReportDatabase_” that is always in an unmounted status. Since the database is not mounted, it reports as a failure in the section “Exchange Server Health” for the column “MB DBs Mounted”.
Adding these databases to the ignorelist cleans up the noise about them later in the report, but it appears that the ignorelist is not used in the first part of the report that generates the per-server health. They were also causing the MAPI test to fail but I was able to get around that by tweaking the code to only attempt a MAPI test for mounted databases.
Any thoughts about incorporating the ignorelist into the earlier part of the script?
Also, during the MAPI checks it looks like the line
foreach ($db in $mbdbs)
should probably be
foreach ($db in $activedbs)
The Real Person!
The Real Person!
Seems to be a bug. One of many that’s crept in over the years. I’ll see what I can do, but yeah if you spot fixes like that by all means update your copy of the script. Always happy to have bugs/issues and their fixes reported on Github as well where I don’t lose track of them.
Hi,
firstly great script, thank you.
Recently the emailed reports have come through as horrible looking txt, rather than pretty HTML – I suspect after installing the last lot of MS Critical patches to both server 2012 r2 and server 2008 r2.
Does anyone have an idea either which one, or what it is and how to fix it please ?
Thanks.
Great work…!!! thanks
Jesus, Paul you must have the patience of a saint replying to some of these comments! (“Please make it PS1.0 compatible” – my reply would be much less measured. 😉 )
Let me add my thanks for making this.
Excellent script. In one environment I get a lot of “Quota violation” (like on the ping check) and “WARNING: Call cancelled”. Next time I run it it works so it seems pretty random. Any ideas?
The Real Person!
The Real Person!
Maybe related to this?
https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/11087637-test-connection-throws-quota-exception-when-passed
I suspect not since I run the check against 4 servers. I tried narrowing it down to only run it against 1 server and every time I get:
—— Checking SERVER01
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 2563
Server version: Exchange 2013
Roles: ClientAccess
WARNING: Call cancelled
Client Access Server Role Services : Fail
—— Finishing
Running CU12 and 2012 R2. Let me know if there are any manual tests you want me to perform to troubleshoot.
Doing a manual Test-Connection SERVER01 works fine.
I did a restart of the Exchange server in question and it seems like this solved the problem. I will do the same with the other servers to see if this solves the problem. So maybe the 100+ days uptime is the cause 🙂
Hello,
Still amazing your script. I have just add a modification a long time ago and just reported it to your last version because we are in 2010/2013 cohabitation now, so I need to run your script on the 2013 server instead of the 2010 like said in your documentation.
I just wanted to put this modification here. The goal of my modificaiton is to have the script running every 15 min and send an e-mail only if necessary :
##### ADDED by Pierre-Yves Pavageau
##### This part is added at the line 175 (after the SMTP parameters)
##### Script is started every 15 min by a scheduled task
##### Every 24h an e-mail is sent just to inform that the script is still working
##### If i do not receive this e-mail i check the script or the Scheduled task to see what could be wrong
$ErrorFile = “$myDirerror.txt” # # I am using a file to write error or OK in it (see below the second part of my modification)
$ErrorValue = Get-Content $ErrorFile
$compteurFile = “$myDircompteur.txt” I am using a file to increment a value in it (15min * 96 = 24H)
[INT]$cptDay = Get-Content $compteurFile
if($cptDay -eq 96) # (15min * 96 = 24H)
{
$cptDay = 1
$cptDay | Out-File $compteurFile ## Setting back to 1 the value in the file compteur.txt
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = $smtpsettings.SmtpServer
## Generate the report and email it as a HTML body of an email
$emailContent = “This e-mail is sent just to confirm that the Script which monitors Exchange functionnality is still working. Next e-mail in 24H.”
$MailMessage2 = New-Object system.net.mail.mailmessage
$MailMessage2.from = $smtpsettings.From
foreach ($smtpsetting in $smtpsettings.To)
{
$MailMessage2.To.add($smtpsetting) ## Email recipient
}
$MailMessage2.Subject = “[EXCHANGE] MONITORING WORKING FINE” ## Objet du mail
$MailMessage2.IsBodyHtml = 1
$MailMessage2.Body = $emailContent
$SmtpClient.Send($MailMessage2)
}
elseif($cptDay -lt 96)
{
$cptDay +=1
$cptDay | Out-File $compteurFile
}
##### ADDED by Pierre-Yves Pavageau
##### This part is added at the line 2090
##### If no issue is found, then no e-mail is sent
##### If no issue if found but we had an issue at the last scan we send an e-mail to inform that is back to normal status
##### If issue is found, then an e-mail is sent
I changed this :
if ($SendEmail)
{
if ($alerts -eq $false -and $AlertsOnly -eq $true)
{
#Do not send email message
Write-Host $string19
if ($Log) {Write-Logfile $string19}
}
else
{
#Send email message
Write-Host $string14
Send-MailMessage @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF8)
}
}
To this
if ($SendEmail)
{
write-host “We will send an e-mail”
if ($alerts -eq $false -and $AlertsOnly -eq $true)
#if ($alerts -eq $false)
{
#Do not send email message Except if ErrorValue is set to Error
Write-Host $string19
if ($Log) {Write-Logfile $string19}
write-host “Display the error value $($ErrorValue)”
if ($ErrorValue -like “Error”)
{
Write-host “There is no more errors or warning”
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = $smtpsettings.SmtpServer
## Generate the report and email it as a HTML body of an email
$emailContent = “This e-mail is sent just to inform you that the EXCHANGE infrastructure is back in normal status.”
$MailMessage2 = New-Object system.net.mail.mailmessage
$MailMessage2.from = $smtpsettings.From
foreach($smtpsetting in $smtpsettings.To)
{
$MailMessage2.To.add($smtpsetting) ## Email recipient
}
$MailMessage2.Subject = “[EXCHANGE-MONITORING] BACK IN NORMAL STATE” ## Objet du mail
$MailMessage2.IsBodyHtml = 1
$MailMessage2.Body = $emailContent
$SmtpClient.Send($MailMessage2)
# Writing OK to error file
$temp1 = “OK”
$temp1 | out-file $ErrorFile
}
}
else
{
#Send email message
Write-Host $string14
Write-host “We found a warning or a fail in the report, so we send the e-mail”
Send-MailMessage @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF8)
# Writing Error to error file
$temp = “error”
$temp | out-file $ErrorFile
}
}
We have a large environment for a customer that has some other business units that have a separate contract for their Exchange servers that are part of the same Exchange Org. We do not manage or have access to those servers.
I am looking for the best way to use your script to only report for our servers.
I have attempted to use the -serverlist switch but it only reports on the servers and not the DAG and database information on those server. Using the ignorelist.txt is a little impractical because its a very long list and new servers don’t necessarily get communicated to us.
Also we have to run the script multiple times to split up our servers and DAGs just to keep the report to a manageable small size.
So wanted to see options before I delve into modification of the script.
@Jeff
If you are in the same Exchange Org, isn’t it possible to do this :
Get all the servers in the Org,
Filter the list to keep only the one you have under monitoring
Add the servers not managed by your self to the ignorelist.txt
Let me know if it helps ?
Hello,
Firstly thanks for the code.
As localised exchange /powershell are, there are some glitch with french version. (Or french a glitch on it’s own ? 😉
The mailflow routine return “Réussite” and not “Success” , while it’s OK in the case of a “fail” , because anything different than “Réussite” or “Success” is either and error or a fail.
so for exchange 2013 french localized modify as is :
line 1141 :
if ($e15mailflowresult -eq “Réussite” -or $testmailflowresult -eq $success )
line 1176 :
if ($testmailflowresult -eq “Réussite” -or $testmailflowresult -eq $success)
and then script will return correct value in the report
The Real Person!
The Real Person!
In the blog post above there’s instructions for how to use the existing variables in the script to handle language issues.
I agree. I partially did but for $success , I was not sure it needed to be edited or not because of being used to partially localized command return ..so I went ahead only editing smtp.
then got error for the mailflow.
So , looking closely on line 1176 and 1141, I found that one (1141) as a -eq test with $success and the other one with -eq “success” -or -eq $success and since I initialy dit not localized $success at all and powershell wont return “success” anyway , that’s why I had a wrong return here.
but I forgot about that $success declaration of you.
goldfish mode 🙂
thank you
Hi Paul, first of all thank you for this script that is useful.
I would like your comment with the following drawback: I have the Escript in scheduled tasks and run it does not show me the following information:
Database Information
Exchange Server Exchange Exchange DB DB (GB) Number of Users
Backup Exchagne Details
Database Server Name Last Name Last Full Backup Incremental Backup
But if I run without the Task Scheduler if you show me the entire report.
First of all thanks
Thanks for the script. Its very much helpful for us. Can you please advise how to get only “Database Availability Group Health Details” table on the email, since we have planned to send this report alone to all L1 and L2 support guys and we do not wish to send them all other details.
almost done then got this:
Mail flow test: WARNING: Connecting to remote server mb2 failed with the following error message : The WinRM client
cannot process
the request. It cannot determine the content type of the HTTP response from the destination computer. The content type
is absent or invalid. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
Hi Paul,
Excellent script.
I’ve been having problems with it not detecting my lagged copies propery. There are 4x copies that are lagged at 2 days. The script does not report them as a lagged copy and errors against the given DAG copy, as the replay queue is quite high.
It seems the script is not returning the lagged copies under variable $replaylagcopies
When I echo the command to the console with the “Where-Object {$_.Value -gt 0}” filter it returns no copies. When I run the command without the filter it returns all copies:
$database | Select -ExpandProperty ReplayLagTimes
[DCA-EXCH-MBX01, 00:00:00]
[DCA-EXCH-MBX02, 00:00:00]
[DCB-EXCH-MBX03, 00:00:00]
[ADLHB-EXCH-MBX4, 2.00:00:00]
Given this it seems the filter is not matching correcty.
I’m running Exchange 2013 SP1 CU13 (current) on Server 2012 R2.
I did try this script out in January with CU11 and had the same issue, so I don’t think it’s been caused by a recent CU.
Would much appreciate your insights.
Jason
Hi Paul / All,
I solved this after also discovering that it was returning a null value for the activation preference. I noted that Sanju (December 29, 2015 at 4:31 pm) provided a fix for the null preference value above.
Applying the same logic to the lagged copy checks works. It’s probably a little messy but it works.
Would like to hear of a ‘correct’ fix!
Old:
$replaylagcopies = @($database | Select -ExpandProperty ReplayLagTimes | Where-Object {$_.Value -gt 0})
New:
if ($database.AdminDisplayVersion -like “Version 14.*”)
{
$replaylagcopies = @($database | Select -ExpandProperty ReplayLagTimes | Where-Object {$_.Value -gt 0})
}
else
{
$replaylagcopies = $dbcopy.ReplayLagStatus
}
#End New commands
if ($($replaylagcopies) -match “True”)
{
[bool]$replaylag = $false
foreach ($replaylagcopy in $replaylagcopies)
{
$tmpstring = “$database is replay lagged on $mailboxserver”
Write-Verbose $tmpstring
if ($Log) {Write-Logfile $tmpstring}
[bool]$replaylag = $true
}
}
I have seen this issue since at least CU 11 and maybe on CU 10. My fix has always been to update the scripting machine to the same CU as the exchange servers.
Hi Paul,
Thanks very much for the script. Works really well. We had it running on an Exchange 2010 box fine then and moved it to a box on a different subnet. The script runs fine on the new box and all status data is returned. All apart from it says the “File Share Quorum = Failed” for all of the mailbox servers in the cluster. I ran the Test-ReplicationHealth cmdlet from the new server hosting the script and all comes back green. I’ve checked the firewall rules and nothing appears to be getting blocked. Any ideas please and thanks in advance.
The Real Person!
The Real Person!
Apart from the different subnet, what is different about the server you’re running it from now?
Thanks for your quick response. The server I’m running it from now is a non-Exchange 2010 server. Thats the only difference really. This new server is on the same subnet as the server hosting the file share quorum so its not a firewall issue.
I fully appreciate its probably an issue with our environment, but I just found it odd that the 99.9% of the health check is successful and the only thing that fails in the ‘File Share Quorum’ check. I’ve checked permissions from our new server to the Quorum and those seem OK.
I’d be happy to continue running the script on an Exchange server, but our monitoring reports high ‘RPC Requests Outstanding’ alerts when the report runs and these don’t reduce even after the script runs. To clear this we need to reboot the server.
The Real Person!
The Real Person!
Basically the script is running (or should be running) Test-ReplicationHealth against each DAG member.
E.g. if you have DAG members named SERVER1 and SERVER2, the script is running…
Test-ReplicationHealth -Server SERVER1
Test-ReplicationHealth -Server SERVER2
…and including the results in the report.
Now, if you’re seeing those commands running manually and returning a pass, while the report still shows a fail, that is odd behavior. In which case, run the script with the -Log parameter and send me the log file and HTML report file to feedback at practical365.com and I will take a look at it.
Hi Paul,
Thanks for the great script.
I’m running through an issue when sending the report through e-mail.
==========================
VERBOSE: Sending email report
WARNING: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated
==========================
All the instances I’m running the script on Exchange server (2013; CAS & MBX roles on same box) itself.
When I run this script with an account that has “Organization management” permissions it executes well and sends e-mail to both external and internal recipients.
Here we would like to get this done with a non-admin account with less privileges.
So, Created a new account with mail box “svc-testhealth”
Added the account to “View-Only Organization Management” Group
Added the account to local admin group on all exchange servers.
It runs successfully on the exchange server and logs the information both on shell as well to file, but when it tries to send a mail it fails with above error.
Can you help me on this?
Regards,
PC
Paul,
Thanks for this script. I’ve been using for some time now in our 2010 environment and its beautiful. I noticed when we moved to 2013 its showing our shadow copy queues in the report. Is there a way to exclude shadow copy queues? This is giving a failure on the server transport queues because the shadow copy queues are above 200.
The Real Person!
The Real Person!
Try this fix:
https://github.com/cunninghamp/Test-ExchangeServerHealth.ps1/issues/5
Wow! Thanks for the prompt reply Paul! As always you and your site are an excellent resource for any exchange administrator.
Keep up the great work!
Hi Paul,
I have implemented this script to run for each site in my infra but recently experiencing issues where it takes more than 8 hours for it to complete and show results. Is there a reason that you can share for script to take such a long time?
Quick info:
Exchange 2010 only.
I execute this script from server with HT role.
I run this using schedule task and configured it to terminate if it runs above 8 hrs.
Only changes to your script that i use is to check for DAG from the current site.
Request urgent assistance with this.
The Real Person!
The Real Person!
Have you tried just running it manually and see where it gets slowed down? Or reverting your changes and try the original script without modifications?
Yes. Manual run generates results but again it takes lot of time and i observed it gets paused while running around half way but starts again after a pause of and hour plus.
The Real Person!
The Real Person!
Is that with or without your modifications?
Thanks for providing this script. It has been really helpful in getting an overall glimpse at my Exchange environment. I have encountered one problem recently after upgrading my Exchange 2013 servers to CU12. When I run the script now I get reported errors that Mail flow has failed on all of each Exchange 2013 server. When I look at the log file I see this:
05/24/2016 06:02:32 Checking mail flow
05/24/2016 06:02:32 The term ‘Test-Mailflow’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
05/24/2016 06:02:32 Mail flow status is Fail
The script ran fine before the upgrade to CU12 and I am running it with elevated privileges. I have also updated to the latest version of your script with the same results. Do you have any ideas what could be wrong? Thanks for any help you can provide.
Muchas gracias, fue de gran utilidad tu script
Paul,
I am running this script and while I am not getting any errors – the report comes out but there is an issue Id like to resolve without removing these hybrid servers completely out of the script entirely.
I have 8 HUBS, 4 are set up to communicate with Exchange Online. That being said, the Test-ServiceHealth will always fail on these, multi-role Hub/CAS servers because the MSEdgeSync Service is not needed.
Is there any way to avoid this, to cont to work in the script on everything else.
The Real Person!
The Real Person!
I just start the service (and set it to auto start too). The script doesn’t have the logic to tell whether an Edge Subscription exists or not, it just uses what Test-ServiceHealth considers to be a good/bad result.
hey Paul, love your site BTW.
I am trying to run the health check report on my two 2013 exchange servers (both are build 1044.25) and keep running into the error below when attempting to email the report, and it happens on both servers:
mail flow test: WARNING: Connecting to remote server mail.mydomain.com failed with the following error message : WinRM cannot process the request. The following err
or occurred while using Kerberos authentication: Cannot find the computer mail.mydomain.com. Verify that the computer exists on the network and that the name provid
ed is spelled correctly. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the argument, and then try running the command again.
At C:WindowsSystem32Test-ExchangeServerHealth.ps1:426 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
Dear Paul,
Hope you are doing well!.
While i trying to run the script, its running almost okay, but at the end i am always getting an error as given below,
You must provide a value for this property.
+ CategoryInfo : NotSpecified: (0:Int32) [Get-MailboxDatabase], DataValidationException
+ FullyQualifiedErrorId : 15FA16A2,Microsoft.Exchange.Management.SystemConfigurationTasks.GetMailboxDatabase
Please help me in this case.
Thanks and Regards,
Shahir
in the report its say DB redundancy and availability is n/a, whats the reason for that?
thanks, great script
The Real Person!
The Real Person!
Depending on the design of the DAG and where the active DB copies happen to be at the time the script runs, some of those items are not applicable.
We had a failed copy a few days a go and the report showed those fields as *FAILED*. Once we resolved the issue, they went back to saying na. Shouldn’t it report “Passed” instead?
Thanks
The Real Person!
The Real Person!
Which fields said “n/a”?
Hi,Paul, thanks for the great script. I have a error when run the script.
—— Checking CAS03
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 824
Server version: Exchange 2013
Roles: ClientAccess
Could not test service health. : System.Management.Automation.RemoteException: Not installed on CAS03.electric.com
Microsoft Exchange 2007 Server Roles
Is there something wrong in my server config ? thanks.
I have three cas server ( exchange 2013 ) , All of them “Could not test service health” , and show “System.Management.Automation.RemoteException” , look like something about exchange 2007 that I have not in my environment.
Sorry , I see the page “Exchange 2013 Test-ServiceHealth Doesn’t Work for Client Access Servers” , that is exactly my situation . Thanks a lot.
The Real Person!
The Real Person!
Some test cmdlets just break if it’s a CAS-only server. I don’t plan to spend much time trying to fix it, sorry. I am investing time in an entirely new script instead. It’s also recommended to not deploy dedicated CAS, and instead deploy multi-role servers.
Paul, thanks for a great script. Quick question, have you considered modifying this script to check for proper log truncation (or does it already do it and I missed it)? Specifically, our backup software regularly issues VSS log truncation requests to Exchange, however some issue with Exchange prevents the logs from truncating. Over time we get notified when disk space runs low, but this script seems like a natural place to check for log file age/truncation.
The Real Person!
The Real Person!
Yes. At the moment I’ve got that in a separate script, because many people like to run it on a separate schedule and have it go to a different set of recipients:
https://www.practical365.com/set-automated-exchange-2010-database-backup-alert-email/
I’ve also written it into Exchange Analyzer (https://exchangeanalyzer.com)
But in the next iteration of the health check script I imagine I will be incorporating that, as it makes sense for them to be together.
Hi Paul, Great work.
This part of the script executes fine for every server in my environment except for one 🙂
It runs fine on that server only when I replace $e15mailboxserver with its FQDN.
i.e:
$url = “http://hostname/powershell” – works for every server except one
$url = “http://hostname.domain.com/powershell” – Works for the recalcitrant server
########################################################################
if ($url -eq $null)
{
$url = “http://$e15mailboxserver/powershell”
}
try
{
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $url -ErrorAction STOP
}
########################################################################
Any suggestions???
Thanks!
Made a few changes on the script. As this is a health checkup, added few tables related the status of the database. But couldn’t find anywhere to upload to you guys to verify.
The Real Person!
The Real Person!
Github (link in the article) is the best place to submit specific feedback.
Hi Paul,
Thanks for sharing such a wonderful script. One thing I noticed is that the “Client Access Server Role Services” and the “Hub Transport Server Role Services” are shown as fail (RED) on the email that’s generated. The “Transport Queue” is shown as “Unknown” (Yellow) whenever the script runs from a daily scheduled task on one of my CAS Array member. Everything else is GREEN. I’m using Exchange 2010 SP3 in a CAS Array (2 servers with CAS, HT roles) and a DAG (2 Servers with Mailbox Server roles ) environment.
Please see below for the Task parameters:
Program/Script: C:WindowsSystem32WindowsPowerShellv1.0powershell.exe
Arguments: -ExecutionPolicy Bypass -NonInteractive -Command “& ‘C:TempPSTest-ExchangeServerHealth.ps1’ -ReportMode -SendEMail”
However, if I run this script below from a PowerShell session on the same CAS array member where I have the task scheduled, the generated email shows all green.
Test-ExchangeServerHealth.ps1 -ReportMode -SendEMail
Any reason for this behavior?
Thanks in advance,
Joe Zapata
The Real Person!
The Real Person!
Are you using the recommended scheduled task settings?
I was able to create this batch file to run either on demand or using task manager. I works as a batch file but need to add the -sendemail parameter and not sure how to do it. Also need some help to run this as a scheduled task.
@ECHO OFF
SET ThisScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ThisScriptsDirectory%test-exchangeserverhealth.ps1
PowerShell -NoProfile -ExecutionPolicy Bypass -Command “& ‘%PowerShellScriptPath%'”;
I was able to create this batch file to run either on demand or using task manager. I works as a batch file but need to add the -sendemail parameter and not sure how to do it. Also need some help to run this as a scheduled task.
i have been using this script on my enviroment of EX2010, but now, im tring to use it on the new Exchange 2013 env. all the test are OK, but i never recive the email report… i have allready configured the smtp settings, and are OK. I try to use sendmail and its working too.
any ideA?
Thanks for the script Paul.
I’m facing issue in scheduling this script from the task scheduler. I get the wrong report in which the “Up time hrs comes with “Unable to retrieve up time ” and Client Access Server Roles Services “fail”. But when i run this script through windows power shell the report comes perfectly, without any issues.
I used the same arguments which you have mentioned in your comment earlier.
can you please tell me how can i get the correct report through task scheduler.
Hi Paul,
This script and none of my other reporting scripts are working anymore since we have applied the Microsoft patches from January 2016. It basically comes down to the part where “get-mailboxdatabase -status” loads the list of servers from memory but that fails (at least.. that is what I suspect). It gives me the output: “you must provide a value for this property”.
I am running Exchange 2010 SP3 RU11 on W2008R2 SP1
Did you or any one else run in to this problem?
The script works great when running from my Exchange 2013 servers, but ran into some fields missing from the report when running the script on a non-Exchange (but tools installed) host.
For the activation preference data that was missing from the report, I followed this comment for the fix: https://www.practical365.com/powershell-script-exchange-server-health-check-report/#comment-197858
The other item missing from the report were the server names from the ‘Database Availability Group Member Health’ section.
This was due to the variable $dagmember.names not providing the same value as it did when the script ran directly on an Exchange server. To fix that issue, I ended up just using the $dagmember variable directly.
Please ignore the above post. I was not using the -ReportMode parameter. It is now giving me error with gmail authentication which I should be able to fix by disabling dual app verification
Hi Paul,
My issue has been resolved after starting services on passive server. However, when run the script I only get the report on powershell and do not see HTML or email.
I already modified email parameter and authentication to gmail. I do not get error with script but runs report only on pshell
Thanks for your response Paul. I will try -log and send you the log. Friday night I exported and imported certificate from active server and change all CAS, we, autodiscover, activesync services to same FQDN as active server. I did not create second host A on public DNS with different public address and NAT on firewall yet. First I wanted to test internal communication before making changes to my firewall and public DNS.
I shut down the active server to see the communication from internal Outlook client and it changed to disconnected, until I rebooted the active server and rebooted passive following that. So, I got a feeling there is still issue with mal flow services, outlook anywhere proxy on passive as database replication health is good
Excellent script, Paul. Thanks a bunch for writing and maintaining it for the community. I encountered some of the same issues as others noted above, and have come up with the following resolutions for them:
Server name is blank in DAG member health table:
change line 1530 to
$memberObj | Add-Member NoteProperty -Name “Server” -Value $($dagmember.Name)
– the ‘$dagmember’ variable is just the string, there’s no ‘name’ attribute
change line 1532 to the following to also fix the verbose logging
$tmpstring = “—- Checking replication health for $($dagmember.Name)”
Exchange 2010 DAG health table shows only ‘n/a’:
change line 467 to
$e14replicationhealth = Invoke-Command -Session $session -Args $e14mailboxserver {Test-ReplicationHealth $args[0]} -ErrorAction STOP
– the function is called with ‘$dagmember’ as the argument; related to the $dagmember issue above
Running in Remote PowerShell:
If you have an active Remote Powershell session to an Exchange 2013 server, commenting out lines 503-521 will allow it to work flawlessly. This just removes the check for the local snap-in.
Thanks again for all your work!
Andy
copy/paste fail… Sorry all. here’s the fixed lines 1530 and 5132
1530: $memberObj | Add-Member NoteProperty -Name “Server” -Value $dagmember
1532: $tmpstring = “—- Checking replication health for $dagmember”
Andy
i am getting below error while running this script
WARNING: No snap-ins have been registered for Windows PowerShell version 4.
i am using Remote powershell.. version is 4 and i have first connected with exchange organization..
my all exchange commands are running fine.. excerpt this script
The Real Person!
The Real Person!
Install the Exchange management shell on the server/workstation you want to run the script from. I haven’t tested it in remote powershell (due to the way the script was originally written) and don’t have any plans to fix this version for remote powershell, but a future version might support remoting.
Hello Paul, thanks for this script!!
I have a question: We just added a new mailbox server to a 3rd. DAG we have. All seems to work fine but:
– Mail Flow Test appears as “Fail” in 3 MBX servers out of 13 servers. We are running the script from a CAS.
– On the DAG Tests, on the 3rd. DAG, The folloging fields appear as “n/a” for the new mailbox server: DB Copy Suspended, DB Initializing, DB Disconnected, DB Log Copy Keeping Up, DB Log Reply Keeping UP.
Any idea what this could be?
Kind Regards,
The Real Person!
The Real Person!
The “n/a” aren’t a concern because some tests are not applicable if the DAG member isn’t hosting any active database copies at the time.
For the mail flow test, run the script with -Log and email the log to me, paul [at] this domain.
Excellent! I will send you the log. Thanks from Mexico!
I get this warning, is it normal?-
ARNING: The file C:certignorelist.txt could not be found. No servers, DAGs or databases will be ignored.
—— Checking EXC-DAG
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 87
Server version: Exchange 2013
Roles: Mailbox, ClientAccess
Mailbox Server Role Services: Fail
Client Access Server Role Services: Fail
Unified Messaging Server Role Services: Fail
Hub Transport Server Role Services: Fail
Total Queue: 1
Mailbox databases mounted: Pass
Mail flow test: No active mailbox databases
—— Checking FAB-EXCH13
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 186
Server version: Exchange 2013
Roles: Mailbox, ClientAccess
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 2
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: Success
WARNING: Windows Failover Clustering encountered a transient error. Trying the operation again may be successful. Error: ‘IsNodeClustered’.
—— Finishing
Can you help me with a health check script for application servers in Linux SUSE environment? Kindly drop the link here please
I have this error while trying to execute this PS
I have Exchange 2010 SP1
Pls Help
PS C:ScriptsExchangeServerHealth> .Test-ExchangeServerHealth1.ps1
The ‘<' operator is reserved for future use.
At C:ScriptsExchangeServerHealthTest-ExchangeServerHealth1.ps1:112 char:13
+ <!– < <<< –>
+ CategoryInfo : ParserError: (<:OperatorToken) [], ParseException
+ FullyQualifiedErrorId : RedirectionNotSupported
Paul,
This script is great! I have one small issue that I can’t figure out. The Server field for the Database Availability Group member health shows up as blank. All the other fields in that table are fine, just no entries for the Server column. Any ideas?
The Real Person!
The Real Person!
Generate a log file for the script (use the -Log switch) and send it to me at paul (at) this domain, and I’ll take a look.
Hi,
I am trying to run this script and get the following error:
â?” $OS.ConvertToDateTime($OS.LastBootUpTime)
[int]$uptime = ” : Unexpected token ‘â?” $OS.ConvertToDateTime($OS.LastBootUpTime)
[int]$uptime = “‘ in expression or statement.
+ CategoryInfo : ParserError: (â?” $OS.Convert…int]$uptime = “:String) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
Can someone please advise what I am doing wrong here please.
Thanks
Paul
The Real Person!
The Real Person!
Have you modified the script? I’m not sure where the “â” character in your error is coming from.
Hi Paul,
Same error here when i took the script from Script Center. No problem if you take it frome Github.
0livier.
The Real Person!
The Real Person!
Still works okay for me when I download a fresh copy, but perhaps there’s something wrong in the script center somewhere. I’ll make a note to refresh the copy hosted there.
Copy script into ISE and resave it. I got the same error saving it from Notepad++
Hi Paul,
Do you think it would be possible, for the mail flow test, to target a specific mailbox? (e.g. administrator..)
I’ve been struggling with antispam and cannot whitelist the “systemmailbox….” email address.
Thanks.
Just for the record if anyone wants to send it to multiple recipient and not a DL I modified it as below to make it work,
$smtpsettings = @{
To = “Recipient 1 “, “Recipient 2 “, “Recipient 3 ”
From = “reporting@xx.com”
Subject = “$reportemailsubject – $now”
SmtpServer = “smtp@xx.com”
}
Dear Paul,
Just to update on this. I fixed the Activation Preference and Server names for Replication Test by using the below.
if ($database.AdminDisplayVersion -like “Version 14.*”)
{
$pref = ($database | Select-Object -ExpandProperty ActivationPreference | Where-Object {$_.Key -eq $mailboxserver}).Value
}
else
{
$pref = $dbcopy.ActivationPreference
}
This worked out and the report is having the correct output.
I am also figuring if when using the Alerts Only Switch can we send the message with the error. Suppose the Queue is high we say the queue is high which is ok but if we can mention the current value that would be amazing… I will update if i can make this happen.
Thanks again
Just used the value with the queue output and worked flawlessly, Now the Alerts have the numbe rof queue as well..
Pingback: 生成Exchange服务器2016/2013/2010环境健康报告 - Exchange中文站
I have been using all the versions when it started back in the days of this script. However I have a challenge now. My client loves this report. But he wants me to take away the email part which I can do and host the HTML as a dashboard and refresh every 20 minutes from the server. Is it something possible to do. Maybe creating an IIS site or something. I am still thinking aout this and thought would ask the experts here.
The Real Person!
The Real Person!
Try using the -ReportFile parameter to output the HTML file to a folder that is configured as an IIS virtual directory.
Kewl Thanks. One other thing. When Using the parameter -Alerts only is it possible not to have the complete HTML and just send the alerts found. Also what if I don’t want this as an attachment and need it in the body of the email.
Thanks again for the help. This script is marvelous and a life saver for Admins like us…
Also I noticed on the Activation Preference Table the values are empty. Any thoughts on that.
Dear Paul,
For me all looks good now…accept no server name in the Replication tests and Activation preference table is blank. I customized the script a bit for the Alerts Only to send the Server Summary and Dag Summary 🙂 Works like a charm.
Any ideas why the activation preference and server names on replication tests are blank…
Important question mailflow test is external or internal
The Real Person!
The Real Person!
Internal.
Hi!
I executed .ps1 in powershell success and I receive mail correctly.
I configured scheduled task and I receive mail void.
The log shown:
=====================================
Exchange Server Health Check
=====================================
Initializing…
Loading the Exchange Server PowerShell snapin
Setting scope to entire forest
The file C:Scriptsignorelist.txt could not be found. No servers, DAGs or databases will be ignored.
Retrieving server list
Removing servers in ignorelist from server list
Servers to check:
Beginning the server health checks
Beginning the DAG health checks
0 DAGs found
0 DAGs will be checked
0 DAGs to check:
0 No DAGs found
This is surprise! Do you know case? How I can fix it?
Thanks in advance
The Real Person!
The Real Person!
Have you followed the suggestions in the article about the scheduled task settings?
Hello Paul,
The latest script is ran from the exchange server which is only CAS and Mbox, dc is on the same vlan. I am able to create “New-PSSession” as you can see below. From what i can gather i see that the script is trying to create a “remote” session to the local exchange server? I also tried it from a diff server on the same vlan and i was able to open a new ps session as admin without get-credential
Can you give me any hints?
[PS] C:Usersadministrator.RACKALLEYDesktop>New-PSSession
Id Name ComputerName State ConfigurationName Availability
— —- ———— —– —————– ————
9 Session9 localhost Opened Microsoft.PowerShell Available
[PS] C:Usersadministrator.RACKALLEYDesktop>Enable-PSRemoting
WinRM Quick Configuration
Running command “Set-WSManQuickConfig” to enable remote management of this computer by using the Windows Remote
Management (WinRM) service.
This includes:
1. Starting or restarting (if already started) the WinRM service
2. Setting the WinRM service startup type to Automatic
3. Creating a listener to accept requests on any IP address
4. Enabling Windows Firewall inbound rule exceptions for WS-Management traffic (for http only).
Do you want to continue?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is “Y”): A
WinRM is already set up to receive requests on this computer.
WinRM is already set up for remote management on this computer.
Confirm
Are you sure you want to perform this action?
Performing the operation “Set-PSSessionConfiguration” on target “Name: microsoft.powershell SDDL:
O:NSG:BAD:P(A;;GA;;;S-1-5-21-4179456325-3254648906-924085538-500)(A;;GA;;;BA)(A;;GA;;;RM)(A;;GAGR;;;S-1-5-21-4179456325
-3254648906-924085538-1162)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD). This lets selected users remotely run Windows
PowerShell commands on this computer.”.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is “Y”): A
[PS] C:Usersadministrator.RACKALLEYDesktop>.Test-ExchangeServerHealth.ps1
Initializing…
WARNING: The file C:Usersadministrator.RACKALLEYDesktopignorelist.txt could not be found. No servers, DAGs or
databases will be ignored.
—— Checking MAIL
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 1
Server version: Exchange 2013
Roles: Mailbox, ClientAccess
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 0
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: WARNING: Connecting to remote server “mail-server” failed with the following error message : Access
is denied. For
more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:Usersadministrator.RACKALLEYDesktopTest-ExchangeServerHealth.ps1:426 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
—— Finishing
Done.
[PS] C:Usersadministrator.RACKALLEYDesktop>
I figured it out,
The internal URL for Powershell was set to HTTPS, once i change it to HTTP in ECP>Servers>Virtual Directories>PowerShell (Default Website)>Edit>Internal URL: to http://FQDN/powershell, it succeeded in sending the report to my email with this command:
.Test-ExchangeServerHealth.ps1 -server MAIL -Verbose -reportmode $true -sendemail $true
Credits go to Paul Cunningham for the above command.
Error running the script
Mail flow test: WARNING: Connecting to remote server exchange13.mah.com.mx failed with the following error message : The WinRM client cannot process the request. It canno
t determine the content type of the HTTP response from the destination computer. The content type is absent or invalid. For more information, see the about_Remote_Trouble
shooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the argument, and then try running the command again.
At C:Usersadministrator.MAHDesktopTest-ExchangeServerHealth.ps1:426 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
I have same issue did you resolve
Hi,
All of our MS Exchange Users are unable to search from OWA, error: The action couldn’t be completed, Please try again.
is there any script to find out what is wrong on our Exchange server, Please share.
When the database is mounted on server01, the following error message is generated below.
But, when I failover the database from server 01 to server02 and run the script, there is no issues with the reporting. What would cause the error below? It was confirmed by running the test-exchangeservices that the WinRM service was in a running state on server01.
Mail flow test: WARNING: Connecting to remote server “server01” failed with the following error message : The WinRM client received an HTTP bad request status (400), but the remote service did not include any other information about the cause of the failure. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:SCRIPTSServer_HealthTest-ExchangeServerHealth.ps1:425 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Pingback: Reseed a Failed Database Copy in an Exchange 2016 DAG
Hi Paul,
I want to run this script in my environment to make my life easier, we have a very simple scenario;
Server 1: Hub and CAS roles installed
Server 2: Mailbox role installed
Please let me know what changes should i make as per my scenario and how to run this script, its a bit stupid to ask such things but I am quite new to scripting.
Thanks in advance.
I have MS Exchange 2010 SP3
The Real Person!
The Real Person!
You should only need to change the SMTP settings in the script. Run the script from the Exchange Management Shell to get started. The link to Github in the article has more help info if you need it.
Pingback: Test-ExchangeServerHealth.ps1 V1.15 is Now Available
Thanks for script….it works great !!!!!
Hi Paul,
great script and one I use a lot. Just put it into one of the DAG’s I look after and all is coming back healthy… most of the time. However one of the public folder DB’s which is on our DR site keeps coming back as “Public Folder database not mounted. ” However in the same report I get the PFDB as mounted and healthy. Any time I jump onto the server and manually run the script ( it is on a schedule ) it is mounted and healthy. Server has lots of free resource and event logs are clean with no errors. I can only assume the script is timing out or not getting a correct response. But not all the time. Any ideas what I can look for?
Thanks
Paul
The Real Person!
The Real Person!
Send me a sample report as well as the log file that the script produces to paul at exchangeserverpro dot com and I’ll have a look at it.
Awesome script, Thanks for sharing Paul.
Require one more help, please let me know if there is any script for below mentioned powershell cmds which can provide the output of these cmds in single file or mail,
1) Get-MailboxDatabase -Status | ft name,last* -auto
2) Get-MailboxDatabaseCopyStatus -Server mbx1
3) Get-MailboxDatabaseCopyStatus -Server mbx2
4) Get-TransportService | Get-Queue
5) Test-ReplicationHealth -Identity mbx1 | ft
6) Test-ReplicationHealth -Identity mbx2 | ft
7) Test-MapiConnectivity -Server mbx1
8) Test-MapiConnectivity -Server mbx2
9) Test-Mailflow -Identity MBX1
10) Test-Mailflow -Identity MBX2
The Real Person!
The Real Person!
A PowerShell script is basically just a series of commands. If you already know the commands you want to run, putting them in a script is a very simple step from there. If you’re new to PowerShell scripting then it will be a good learning exercise for you.
Paul, thank you so much for your work!! We have exchange 2013 SP1 2 member DAG on server 2012 R2. I can not get this script to either make the report or send an email using scheduled task. The script does send email when run from powershell with the -sendemail switch/option. I looked through the event logs to see if i could see any error but did not see anything related to the script. I have the exact same settings in the scheduled task as you shared in the article above.
Run whether user is logged on or not
Run with highest privileges
Action: Start a program
Program: powershell.exe
Arguments: -command “C:ScriptsTest-ExchangeServerHealth.ps1 -Log -SendEmail”
I have removed the quotes at the end of the arguments to look like this:
Arguments: -command “C:ScriptsTest-ExchangeServerHealth.ps1″ -Log -SendEmail
and i have entered the full path in the program line:
Program:C:WindowsSystem32WindowsPowerShellpowershell.exe
This task is at the root level of the task scheduler. Not sure what else to try not knowing any error(s). Any ideas?
The Real Person!
The Real Person!
Put the powershell.exe command line you’re trying to run in Task Scheduler into a .bat or just run it from a cmd.exe, see if you get any different errors. Make sure you’re running the .bat or cmd.exe with the credentials you’re trying to run the scheduled task with too.
Thanks for those instructions! Turns out, it did not like the quotes (“) in the command. Removed those and its working like a champ. Thank you again Paul!
Hi Paul,
Thank you for your script.
On my Exchange 2013 (Windows 2008 OS) server when I ran script as domain admin at Exchange Power Shell successfully
cd D:Scripts
.Test-ExchangeServerHealth.ps1 -SendEmail ==> I received report html email.
But when I make schedule task for script (as domain admin too) :
Program : C:WindowsSystem32WindowsPowerShellv1.0powershell.exe
Arguments : -command “D:ScriptsTest-ExchangeServerHealth.ps1 -SendEmail”
It didn’t work, the task completed return code 0 but I didn’t receive any email.
I fixed it by select “run with highest privileges” at task setting.
Hi Paul
very useful report however notice database availability and redundancy is showing n/a the rest is passed
Hey Paul,
Major fan of your work.!
Tell, me, where is the output of the HTML content churned out to prior to invoking the SENDMAIL feature?
PLEASE, SPEAK!
HerbZ
is actually at the C root
Hi Paul,
Great script, it does exactly what it says on the tin!
One question though, is it possible to have the report emailed to more than one address?
I’ve tried separating different email addresses by space, comma and semi-colon but none seem to work.
Any thoughts?
Cheers
Matt
I’m looking to do the same thing and wondered if Paul has any suggestions?
The Real Person!
The Real Person!
Use a distribution group.
mail report show mail flow test failed.,
using .test-exchangeserverhealth.ps1 -server servername
mail flow test : success.
i ‘m using V1.14, 21/5/2015
no idea.
Hi Paul,
Thank you for the script, its a real great help. However, I was hoping to get a more detailed list of the below commands appended into the script:
Get-TransportService | Get-Queue | Sort MessageCount – To view a detailed summary of all the queues
Also if I can pull up Individual Disk Spaces on all the servers with a summary of Free Space, Total Space and Space Consumed
Last but not the least, a detailed summary of the Mailbox Databases and the size and whitespace in case.
I am planning to check the service health of specific DAG servers and its respective CAS and HUB, if I have to create ignore list it will be more in number. Can you please modify script such that I can specify the server list rather than specifying ignore list ?
The Real Person!
The Real Person!
No. But the script is free for you to take it and customize it any way you like for your own specific needs.
for a simple sort of Servers …
#Begin the health checks
$exchangeservers = $exchangeservers | SORT
foreach ($server in $exchangeservers) ….
I get a error message on line 2096:
Send-MailMessage : Unable to connect to the remote server
At C:ScriptsExchangeServerHealthtest-exchangeserverhealth.ps1:2096 char:4
+ Send-MailMessage @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([Syst …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpExcept
ion
+ FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage
Im running this on a Windows Server 2008 R2 with Exchange 2013.
Instead of mail.domain.com I copied the IP Adress of the server. Solved the problem.
Hello Paul,
great script and very usefull to check our Exchange Systems.
I’m getting 2 hours instead of 1780 in Powershell 3 with
[int]$uptime = “{0:N0}” -f $uptime
My fix is
int]$uptime = “{0:N0}” -f $uptime.ToString
The Uptime is now reported correctly.
Hi !
When I receive the e-mail with Exchange Server Health Check Summary, There is the following message:
Server1 – Mail Flow Test Failed
But at Exchange shell when I run Test-Mailflow SERVER1 -TargetMailboxServer SERVER2 , the result was succesfull.
Everithing is working perfectly ! I don’t have any idea why i’m receving this error only at report.
Can you help me ?
The Real Person!
The Real Person!
Does that error always appear in the report or just that one time?
Hy Paul !
Always appear in report.
Hi Paul, thanks for this.
Im running this on an Exchange 2013 Server, and am getting an error on the Mail Flow Test.
Running Test-mailflow is successful, but this script returns an error for the Server it is running fromon
Mail flow test: WARNING: Connecting to remote server ServerMBXpd01 failed with the following error message : The WinRM client cannot process the reques
t. It cannot
determine the content type of the HTTP response from the destination computer. The content type is absent or invalid. For more information, see the
about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Supply an argument that is not null or empty and then try
the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Supply a non-null argument and try the command again.
At C:psHealthReportTest-ExchangeServerHealth.ps1:425 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
The Real Person!
The Real Person!
Which CU are you running? I’ve seen reports of issues like this for some of the older CUs but AFAIK CU9 works fine.
And have you configured the PowerShell virtual directory URLs? Mine are left as the server FQDN and the script works. I think some folks have seen similar errors when their PowerShell URLs are set to an alias.
I just got this same error CU11
PSURL=FQDN
Mail flow test: WARNING: Connecting to remote server xxx-xxxx failed with the following error message : The WinRM
client cannot
process the request. It cannot determine the content type of the HTTP response from the destination computer. The
content type is absent or invalid. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Supply an argument that is not
null or empty and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Supply a non-null argument and
try the command again.
At C:tempTest-ExchangeServerHealth.ps1:426 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
The Real Person!
The Real Person!
Same question as above then.
In my case we change all virtual directory internal URLs to our external mail URL (ex. mail.domain.com). When the script tries to connect to this host for mail flow, it fails with the same error as above. Any suggestions?
managed to fix this. change the internal url for the powershell default to exchange server name with domain (FQDN) instead of load balancer URL, this worked for me.
Pingback: PowerShell Scripts for your Exchange Server Toolkit
Hi Paul,
Firstly, Thanks for the great superb.
We are running Exchange 2013 environment, Script works fine. However, In the output I get “n/a” under Client Access Server Role Services, Hub Transport Server Role Services, Mailbox Server Role Services.
All servers are multi role servers. Could you please help how to rectify/make required changes in the script to get the desired output.
The Real Person!
The Real Person!
That part of the script uses Test-ServiceHealth so see you can run that cmdlet on its own.
Thanks for the quick reply Paul.
I’ve tried to change that part of script to the best of my knowledge which did not work.
Would you mind helping me with exact lines which need updated/modified in the script for me to get the desired output.
Thanks in advance.
The Real Person!
The Real Person!
Don’t change the script, I’m suggesting you run Test-ServiceHealth on its own to see whether it returns an error or gives you some clue as to why the script is not working correctly.
Also if your servers are running non-English language then there are extra steps explained in the article above for what you need to change to get that to work.
Great script, many thanks.
Paul.
hello Paul!
Thanks for an excellent script. I have installed 3 new Exchange Servers, two mailbox and one CAS/HUB, on a remote site.
The weird thing, is that the script is running perfect, on the rest of the servers but on the new CAS/HUB. It returns an error:
Unable to retrieve uptime. Could not test service health. Could not test service health. Could not test service health. Could not test service health.
I´ve check WMI on the server, with no problem. These 3 servers are on a different site, but again the script is running fine on the mailbox servers.
Any Clue that you could give me??
Thanks for this useful script.
But,I am not getting any email after completed the successful execution of the script. I have changed my own SMTPsettings.
Amazing Wonderful..
Love the script & the output is amazing :DDDD
you are the best MAN :DDDD
Hi Paul
How do I make this to send report to multiple recipients?
I tried “user1; user2”, this ends up in an error.
I also tried “user1, user2”, but only user1 ends up getting the report while user 2 seems to be chopped off.
The Real Person!
The Real Person!
Use a distribution list.
Well i overlooked that the Exchange EdgeSync service was down. After starting service everything was fine.
Thnx & regards!
Hello Paul,
the script works fine until last Exchange Rollup 10 update from Microsoft when the Hub Transport Role keeps saying Fail ( – Hub Transport Server Role required services not running )…. but service is running and mail flow is just OK. Tested.
I have Exchange 2010.
Regards
The Real Person!
The Real Person!
Run Test-ServiceHealth on the server and see if any of the required services are not running.
Paul,
It only shows fail when you run the script from scheduled task. When i run it manually from PS Console it shows all ok.
It only shows fail for the server the scheduled task is running from. If i scheduled task from another server it will show fail for that server and the previous server will show pass.
Any idea why this is happening.
i am also looking to get mailbox count for each databases in this script. Is it possible for you to amend the script.
Your help is really appreciated.
Paul,
I would like to request to you if you can add to get mailbox counts on each database in this existing script, that would be great. I trying to consolidate the report for our environment.
Thanks for the reply.
I ran test-servicehealth and it shows all OK.
The problem is which ever server you pick to run this script from, it shows some service fail on that server.
I then tried using Send-MailMessage at bottom of your script andded this report send as attachment and all looks OK.
I think the problem occurs when we use -SendEmail parameter and report comes in a body message.
For NashTek,
You can add this command at the end of this script
Send-MailMessage -To User1@xyz.com, user2@xyz.com -From admin@xyz.com -Subject “$reportemailsubject – $now” -Body “Test Message” -SMTPServer -Attachments
i am too using this method to send report to multiple users.
Hello Paul or anyone else that might be able to offer some insight,
Hopefully this is an easy request. Please tell me how this script can be edited to send email to multiple recipients? I have tried separating recipients in the To: field by comma, semi colon and blank space but nothing works for me when my scheduled task runs. Specifying a single recipient works without issue.
Kind Regards
Here’s something I found from a similar issue that may have some relevance:
The MailMessage constructor you are using only takes one email address. See the MSDN documentation http://msdn.microsoft.com/en-us/library/5k0ddab0.aspx
You should try using Send-MailMessage instead because it’s -To parameter accepts an array of addresses
Send-MailMessage -from from@email.mail -To $recipients -Subject “Disk Space Report – $Date” -smptServer smtp.server -Attachments $freeSpaceFileName
Note: Send-MailMessage was introduced in PowerShell v2.0 so that’s why there are still examples that use other commands.
The script is run from Scheduled Tasks on a Windows Server 2008-R2 server running Exchange 2010-SP3 Update Rollup-9 as follows;
Action:
Start a Program
Program/script:
C:WindowsSystem32WindowsPowerShellv1.0PowerShell.exe
Add arguments (optional):
-command “. ‘C:Program FilesMicrosoftExchange ServerV14BinRemoteExchange.ps1’; Connect-ExchangeServer -auto; C:ScriptsTestExchangeServerHealth.ps1 -ReportMode -SendEmail”
Start in (optional):
C:Scripts
The Real Person!
The Real Person!
Using a distribution list is the easiest solution.
That’s what I decided as well. Thanks for the reply.
Paul,
Thanks for this wonderful script and the work you are doing to help people like us who do not much experience on writing the PS scripts.
I am having one issue with report, the script runs fine without any errors.
The server from which this script is executed it shows in the report that the server role as failed.
I tried running this script on my HT/CAS, MBX role server and it shows same in the report.
But when i execute the script -server parameter the report shows all green.
e.g i am running the script from EXCH01 and generate the report for this only it shows all green, but when run the script against all server with scheduled task or from management shell from server EXCH01 which has HUB/CAS role then it shows HUB Transport Role as failed.
Another thing i noticed is if i execute the script from EXCH02 which is in ignorelist.txt file then report comes out as expected, but if this server is not listed in ignorelist.txt file and the script is executed from this server then it shows role service failed for this server.
I hope i have put down my issue in detail for you to understand and help me fix this.
Thanks in advance for your help.
Shahid
The Real Person!
The Real Person!
Sounds like one of your servers has some services not running. Use Test-ServiceHealth to test that server.
Hello Paul,
I would like to thank not just for this script, but for each and every blog that you have written as it is helping a lot to me in my day to day task.
Regarding Test-ExchangeHealth script, I think for Exchange 2013 MA events or HealthReport should be added.
I am looking for a Exchange 2013 report which will include all database and server health + managed availability health set command result (Get-HealthReport) for all the servers.
I would also like to suggest to add few line to the script which will dig into Managed Availability Logs and find the number of occurrence of probe failure with error description.
To clarify, I obviously can see that the “Test-Mailflow” cmdlet (at least) is being used, but I can’t tell where or what it is testing. (if it helps, I am running Exch 2010, with 1 Hub/CAS server, and a 2-server DAG, I’ll call them “MB1” and “MB2”. I have a single mail database, and it is active on MB1). Here are the results:
—— Checking MB1
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 300
Server version: Exchange 2010
Roles: Mailbox
Mailbox Server Role Services: Pass
Public Folder databases mounted: Pass
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: *FAILURE*
—— Finishing
Done.
Paul (or anyone else), please help!
I had a backup problem over the weekend. My LOGS volume filled up, and my exchange database dismounted. Iwas forced to turn on circular logging and manually restart replication. My servers are both up and everything appears great–EXCEPT that TestExchangeServerHealth script is returning a FAILURE for “Mail flow test” on my active mailbox server.
I have confirmed that my Exchange system is sending and receiving both internal and external email. None of my other tools (SolarWinds, EMC, Mail Flow Troubleshooter) are showing any issues. I tried turning on “-Log” to get more detailed information, but all the log file shows is the same generic info as the screen display.
I have looked in the script, but frankly I am not a PS guru, and I can’t even tell what EMS commands are being used to test “Mail Flow”… Can someone help illuminate what calls are being made so I can at least replicate this failure outside the script?
Thanks Paul!!
Hi Paul,
Really nice work!!!
Can we customize it to show last backup done for databases.
Usually we run the following cmd
get-mailboxdatabase -status | ft name,last* -auto
can we include it in script
The Real Person!
The Real Person!
I have a separate script for that. Here you go:
https://www.practical365.com/set-automated-exchange-2010-database-backup-alert-email/
Hi Paul,
Thanks for the wonderful script.
While there were several errors when script ran:
The term ‘Test-Mailflow’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
The term ‘Test-ReplicationHealth’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a
path was included, verify that the path is correct and try again.
Do you have suggestion about what will be the cause ?
Regards,
Frank
Running above scripts give output on screen no email to HTML file. I modified the email setting no error but no email is also being sent.
The Real Person!
The Real Person!
What is the exact command you are running?
I have saved the script and changed email details like To , from and server details.
than ran the script from Exchange power shell..
06/18/2015 13:10:20 —— Checking PVW0-EXCH-F-UL1
06/18/2015 13:10:20 Checking DNS
06/18/2015 13:10:20 DNS check passed
06/18/2015 13:10:20 Checking ping
06/18/2015 13:10:23 Ping test passed
06/18/2015 13:10:23 Checking uptime
06/18/2015 13:10:23 Uptime is 671 hours
06/18/2015 13:10:23 Server is running Exchange 2010
06/18/2015 13:10:23 Server roles: ClientAccess, HubTransport
06/18/2015 13:10:23 Checking service health
06/18/2015 13:10:24 Client Access Server Role Services status is Pass
06/18/2015 13:10:24 Hub Transport Server Role Services status is Fail
06/18/2015 13:10:24 Checking Hub Transport Server
06/18/2015 13:10:24 Queue length is 1
06/18/2015 13:10:24 Finished checking server PVW0-EXCH-F-UL1
The Real Person!
The Real Person!
That’s the entire log file?
Yes all others parts are good, and I copy only the check of that server. Note that the server giving me that error is in a different AD Site. I am sure that, maybe there is something blocking it through the network. It’s really weird. Thanks for your suggestion.
in which mail can I send you the whole log file?
Thanks
The Real Person!
The Real Person!
You can send me the log at paul at practical365.com, but I’m confused what you’re asking for help with. Is it a problem running the script, or is the script reporting a problem with one of your servers and you’re not sure what to do about it?
Hello Paul,
I cannot find it. It seems that it does not generate anything. I have checked everywhere and event use a tools to look for it without success.
Thank you to guide me.
I am looking forward to hearing from you.
Regards
Hi Paul
I can run the powershell scrip using .Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
and receive the email and a copy of the report in html.
The issue is with the task schedule as the scripts run but I am not receiving emails and log details
In the task schedule I have used your recommended settings.
My scheduled task settings for this script are:
Run whether user is logged on or not
Run with highest privileges
Action: Start a program
Program: powershell.exe
Arguments: -command “C:ScriptsExchangeServerHealthTest-ExchangeServerHealth.ps1 -Log -SendEmail”
could you please advice on this?
The Real Person!
The Real Person!
What does the log file say? If you can’t find it then it may be writing to a different folder. Try searching your C: drive for the log file name, or change the “Start In” setting in the scheduled task to match where the script is located.
Bonjour,
Merci pour ce scripts, j’ai une error peux-tu s’il te plait m’aider parceque j’ai cet error pourtant mon transport server n’a pas de probleme.
—— Checking PVW0-EXCH-F-UL1
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 505
Server version: Exchange 2010
Roles: ClientAccess, HubTransport
Client Access Server Role Services: Pass
Hub Transport Server Role Services: Fail
Merci
The Real Person!
The Real Person!
Run Test-ServiceHealth on that server and it will list the services that need to be started for the test to pass.
When running the script on the “primary” machine the mailflow test fails for that machine. Is this script intended to be ran from outside of the actual exchange machines. The server is server 2012r2 and exchange 13 cu8.
Actual error:
Mail flow test: WARNING: Connecting to remote server failed with the following error
message :
Access is denied. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:PowershellTest-ExchangeServerHealth.ps1:425 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
Hi Paul,
I get the following message when the scripts runs the Mail flow test: Warning: Connecting to remote server xxxxx failed with the following error message: The WinRM client cannot process teh request. The WinRM client tried to use Negotiate authentication mechanism, but the destination computer (xxxxxxx:80) returned an ‘accesss denied’ error. The script was running fine while I was testing before the error appeared. Please advise how to fix this error. Thanks.
Hi Paul, Great script!! Thanks I just want to create a Batch script to have this run, not necessarily through task scheduler. I need the report and email. Can you provide me the script for this? Report PS1 file is located in C:ScriptsExchange Health ReportTest-ExchangeServerHealth.PS1.
Apologies if this is a simple request. Trying to get my head around scripting!!
The Real Person!
The Real Person!
Just put the same info you’d use in Task Scheduler into a batch file instead. In the article above I shared my Task Scheduler configuration.
Hey Paul, great script! I’ve been using it for over two years now.
I’m not sure if it has already been suggested, but I would like to see one small feature added – what server has quorum for each DAG. Currently, I manually use this:
Get-DatabaseAvailabilityGroup -Identity DAG -Status | fl PrimaryActiveManager
It would be nice to see this in your script as well. Just my $.02.
It was a missing quote in one of the email fields. Thanks!
Hello Paul – great script. I’m looking forward to using it. I am however getting an error message when I try to run it:
At D:scriptsTest-ExchangeServerHealth.ps1:549 char:8
+ Write-Verbose $string21
+ ~
Missing ‘=’ operator after key in hash literal.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingEqualsInHashLiteral
The Real Person!
The Real Person!
Did you edit the script at all?
Just the email section and I double checked all the values.
The Real Person!
The Real Person!
Most likely issue is you’ve not closed quotes or brackets properly. Try the script without edits (just let it output to console). If that works then redo your edits and look for typos.
Hi Paul,
The script is amazing and running very smooth.
I have a question:
I have mixed environment 2010/2013, when I run the script against the 2010 CAS/hub server it runs very smooth on the default receive connector.
when I run it against 2013 it doesn’t send email and require authentication.
in the protocol logs, I’ve found that the script is authenticating with the 2010 server by the user that ran the script while this doesn’t happen on 2013.
is there a way to do so or whay does it authenticate with 2010 and doesn’t do so with 2013?
This is the trasport logs on both servers
On 2010:
220 2010Servername Microsoft ESMTP MAIL Service ready at Sun, 3 May 2015 11:47:59 +0300
EHLO
250-2010servername Hello [RemoteIP]
250-SIZE
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-X-ANONYMOUSTLS
250-AUTH NTLM
250-X-EXPS GSSAPI NTLM
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250-XEXCH50
250-XRDST
250 XSHADOW
AUTH ntlm
334
Set Session Permissions
SMTPSubmit SMTPSubmitForMLS SMTPAcceptAnyRecipient SMTPAcceptAuthenticationFlag SMTPAcceptAnySender SMTPAcceptAuthoritativeDomainSender BypassAntiSpam BypassMessageSizeLimit SMTPSendEXCH50 SMTPAcceptEXCH50 AcceptRoutingHeaders AcceptForestHeaders AcceptOrganizationHeaders SendRoutingHeaders SendForestHeaders SendOrganizationHeaders SMTPSendXShadow SMTPAcceptXShadow
DomainUsername ” the user that ran the script” authenticated
235 2.7.0 Authentication successful
—————-
On 2013
220 2013servername Microsoft ESMTP MAIL Service ready at Tue, 5 May 2015 08:20:55 +0300
EHLO
None
250-2013server Hello [Remote IP]
250-SIZE 36700160
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-X-ANONYMOUSTLS
250-AUTH NTLM
250-X-EXPS GSSAPI NTLM
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250 XRDST
AUTH ntlm
334 Inbound Negotiate failed because of LogonDenied
User Name: NULL
Tarpit for ‘0.00:00:05’ due to ‘535 5.7.3 Authentication unsuccessful’
The Real Person!
The Real Person!
I can’t tell anything from that protocol log info because you’ve left out the receive connector detail.
The default frontend connectors on Exchange 2013 allow unauthenticated SMTP to *internal* recipients. So if you have not created any custom receive connectors in Exchange 2013 it should work.
If you *have* created custom receive connectors it’s possible that the custom connector is handling your SMTP connection. The way to tell is to look at the receive connector name in the protocol log entries.
Or simply create a DL that includes those two people?
Hi,
Great scripts and Exchange information. In the script I want to be able to send the email 2 people.
I’ve tried “email1″,”email2” this did not work
“email1″;”email2” this did not work
(“email1″,”email2”) this did not work
(“email1″;”email2”) this did not work
Any ideas?
did you try “email1;email2” ?
The Real Person!
The Real Person!
As Jose suggests, use a DL for this. Much simpler to manage in the long run.
Great work Paul! I really enjoy your articles and scripts.
One thing I get when running this script in my 2 server Exchange 2013 CU6 environment is a Kerberos error against the Round Robin DNS name when doing the Mail Flow Test on the server hosting the database.
This happens as the computer object for the round robin DNS name doesn’t exist.
Any input on getting this to test the actual computer name rather than the round robin DNS name?
Thanks!
The Real Person!
The Real Person!
Can you email me the full error or the full log file (use the -Log switch) to paul at practical365.com and I will take a look.
Some earlier CU’s don’t run the script properly for some reason but yours is the first report of a Kerberos error, as far as I recall.
Did this ever get fixed? I’m experiencing the same with Exchange 2016 CU6, but only if I run it for all servers. If I run it against any individual server, mail flow checks pass. If I run it without the server name switch, it fails when connecting to the round-robin DNS name we use
The Real Person!
The Real Person!
If the script is trying to connect to a PowerShell vdir that is configured with an alias instead of the server FQDN, I believe it fails unless Kerberos auth is fully set up and configured for your Exchange environment.
I apologize if I’m missing something, but does that still explain why running “Test-ExchangeServerHealth.ps1 -Server mailsrv17a” produces a mail flow test with a result of Success, but just running “Test-ExchangeServerHealth.ps1” show a failure on that same server (mailsrv17a)?
The Real Person!
The Real Person!
It might, yes.
Pingback: 8款免费工具对于Exchange管理员 | 爱七七五八网
Hey Paul, do you have any recommendations for me if we have disabled the indexing service on all mailbox servers by design? My environment is 110TB and enabling indexing would require more storage than we want to procure at this time. Is there a way to ignore indexing completely without ignoring the rest of the services on the mailbox servers?
Also, for some reason the log is never created in the directory I am running the script from, and I cannot find it anywhere else on the server. I haven’t modified your script so I am pretty confused.
I’m having trouble setting this up as a scheduled task. I’m using the settings you provided in the post, running on a 2013 CAS server. Running the script manually works fine on the server, but when I set up a scheduled task the result is always successful, but I never receive the report. I’m running the task as a domain user that has org admin rights within Exchange.
Any ideas?
Thanks!
Script runs flawlessly! I do have one question though. What if I want to check my Edge Transport Servers? Where do I edit the script?
The Real Person!
The Real Person!
There’s no edit I can suggest. I haven’t written or tested any Edge server checks. Some of the tests may happen to work against Edge but that isn’t by design.
Fantastic script, thanks for all the hard work! It seems, however, the WinRM is back with CU8. Anyone else experiencing the same thing?
Hey Paul,
Is there a way the dive space for each server in a DAG can show up on this report? or do you have another report that can give me that information?
please let me know
You may want to check this one out
http://shaking-off-the-cobwebs.blogspot.com/2015/03/database-backup-and-disk-space-report.html
Wow, that script of June Castillote is awesome!
I made a less awesome and little simpler modification to the original script of paul. This will check if the free disk space is lower than a specific treshold. Let me know if you are interested in the less awesome solution 🙂
Regards,
Erik
Hello,
This is a great script, love it. But, when I run the script my results say two of my three mailbox servers fail the “Mail Flow test. I verified each server with PS that mail does flow. The error message is below. It appears to have a problem with WinRM Client.
Any help would be great.
Mail flow test: WARNING: Connecting to remote server sjmmail01 failed with the following error message : The WinRM client cannot process the request. It cannot determine the content type of the HTTP response from the destination computer. The content type is absent or invalid. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the argument, and then try running the command again.
At C:ScriptsTest-ExchangeServerHealth-v1.2Test-ExchangeServerHealth.ps1:424 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Nick, I had the same error as you, I upgraded to CU7 and the script now works as expected
Mike
Pingback: 8 Free tools For Exchange Admins | SmashingApps.com
Hi Paul,
when running this scripts, some of the Exchange 2010 servers return:
fyi: I am using v1.12 of the script.
—->
Mail flow test: Write-Log : The term ‘Write-Log’ is not recognized as the name of a cmdlet, function, script file, or op
erable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:ScriptTest-ExchangeServerHealth.ps1:402 char:14
+ if ($Log) {Write-Log $_.Exception.Message}
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Write-Log:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Write-Log : The term ‘Write-Log’ is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:ScriptTest-ExchangeServerHealth.ps1:416 char:14
+ if ($Log) {Write-Log $_.Exception.Message}
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Write-Log:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the
argument, and then try running the command again.
At C:ScriptTest-ExchangeServerHealth.ps1:423 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
<—
any idea what might cause this? It is pretty weird because not all the exchange 2010 servers return this error. Not all 2010 servers are running the same CU, but it does not seem to be bound to a specific CU (error occurs on servers with different CU levels).
The Real Person!
The Real Person!
Whoops, a typo when trying to call the Write-LogFile function… must have been there for a while and gone unnoticed.
I just pushed an update to Github and TechNet Script Gallery that should fix it.
This is a great script and I have been using it for years. However, recently in one of our environments where there is 2 CAS servers and 2 MBX servers, I am getting reports from the script saying ‘Could not test service health’. I run the script on two servers 30 minutes apart from each other. One server does not send the alert, so everything is ok, but the other started sending this regularly about a week ago.
All other tests pass. but for each of the role services on each server, it shows Could not test service health. and ‘n/a’ in its own server roles.
Does anyone have an idea what may have changed to cause this?
Hi,
We do have a strange issue with exchange 2013 where all the emails are in submission queue. All the test and checks are positive. Still cant fihure out why. The exchange server looks fine and seems no issue with it. All the emails are stuck in the queue and does nothing.
The Real Person!
The Real Person!
Get-Queue | Get-Message | Fl
That command will output a bunch of information about the messages in the queue, including any error messages (if any exist).
Hi Paul,
Thanks for the reply. I was able to clear the message queue by restarting the transport services which should do automatically pushing out emails.
Hence, it is not the concern of messages in the queue but its not pushing out by itself.
Exact Scenario: The email reaches the exchange server and just stuck there in the queue. Once the transport service is restarted, it pushes out few e mails and stops again.
I had recreated the send/receive connectors but still doesn’t work.
Just appending the error logs
2015-02-05T00:14:43.859Z,08D208896C3835E1,SMTP,client proxy,>,Established connection to
2015-02-05T00:14:44.258Z,08D208896C3835E1,SMTP,,-,Messages: 0 Bytes: 0 (Remote error from proxy client)
The Real Person!
The Real Person!
If you do a few Google/Bing searches for things like “Exchange 2013 messages stuck in queue” you’ll find a lot of discussion around this topic. It is quite common, but can also be due to a wide variety of root causes. For example:
http://thoughtsofanidlemind.com/2013/03/25/exchange-2013-dns-stuck-messages/
First thing to check is whether you’re running the latest CU version of Exchange 2013 (currently CU7). Some of the earlier builds of Exchange 2013 did seem more prone to this type of transport issue.
Hi
Thanks for the script, I can run it however I get an error on Mail Flow Test (see below)
PS C:INSTALLSEXCHANGE_SCRIPTS> .Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
Initializing…
WARNING: The file C:INSTALLSEXCHANGE_SCRIPTSignorelist.txt could not be found. No servers, DAGs or databases will be ignored.
—— Checking EXCHANGE-SERVER
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 141
Server version: Exchange 2013
Roles: Mailbox, ClientAccess
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 1
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: WARNING: Connecting to remote server mail.DOMAIN.COM failed with the following error message : WinRM cannot process the request. The follo
wing error occurred while using Kerberos authentication: Cannot find the computer mail.DOMAIN.COM. Verify that the computer exists on the network and that
the name provided is spelled correctly. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the argument, and then try running the command again.
At C:INSTALLSEXCHANGE_SCRIPTSTest-ExchangeServerHealth.ps1:410 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
—— Finishing
Sending email.
Done.
The report is emailed OK (I edited the smtp section within the script), I have run the script on all exchange server and get the same result, I think the problem may be due to a missing spn mail.DOMAIN.com but I do not know what it is to registered to, can you help?
Thanks
Mike
The Real Person!
The Real Person!
Which version of Exchange 2013 are you running?
Hi Paul,
I was running CU3, I’ve upgraded to CU7 and now its working (thank you very much) However the CU7 upgrade has made the ForwardSyncDaemon component inactive and I cannot start it!!!!
Many Thanks
Mike
Hey Paul,
I would like to run this script for my environment. Does it require a downtime or anything? I just need to know if its ok to run during business hours or I need to put in a change control as it may cause a temporary down of the servers.
Thanks
The Real Person!
The Real Person!
No downtime required.
Great script. Many thanks!!
I have also written a script in german language to get an overview about Exchange on-premise oraginisations:
http://www.frankysweb.de/exchange-reporter-2013/
Hi Paul,
Script looks fantastic, however I’m running into three issues.
1. Test-ServiceHealth against Ex2007 HUB server generates Watson dump. Below is error message:
////////////////////////////////////////////////////////////
Roles: HubTransport
WARNING: An unexpected error has occurred and a Watson dump is being generated:
Could not test service health. : System.Management.Automation.RemoteException: NotSpecified: (:) [Test-ServiceHealth],
OutOfMemoryException
////////////////////////////////////////////////////////////
2. Mail-flow test against Ex2007 ccr cluster just skips.
3. Mail-flow test against Ex2013 (in dag) that holds active databases fails. Below is error message:
////////////////////////////////////////////////////////////
Mail flow test: WARNING: Connecting to remote server webmail.interpipeline.com failed with the following error message :
WinRM cannot process the request. The following error occurred while using Kerberos authentication: Cannot find the computer webmail.interpipeline.com. Verify that the computer exists on the network and that the name provided is spelled correctly. For more information, see the about_Remote_Troubleshooting Help topic.
WARNING: Cannot validate argument on parameter ‘Session’. The argument is null or empty. Provide an argument that isnot null or empty, and then try the command again. Remove-PSSession : Cannot validate argument on parameter ‘Id’. The argument is null. Provide a valid value for the argument, and then try running the command again.
At X:Custom_ScriptsTest-ExchangeServerHealth.ps1:423 char:19
+ Remove-PSSession $session.Id
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Fail
////////////////////////////////////////////////////////////
Any help is greatly appreciated!
The Real Person!
The Real Person!
For 1 and 2 , the script isn’t tested or intended to work against Exchange 2007 servers.
For 3, that looks similar to an issue raised by someone else. I believe the problem is SSL validation when trying to do a remote PowerShell session. I haven’t looked into a fix yet but it is on my list.
Hi Paul,
I like this new script as it has all information in one script.
But It’s not showing color in Trans Queue like green/yellow/read. though information is written clearly that warning with number of messages/pass/fail.
over all good.
Thanks,
Prakash
The Real Person!
The Real Person!
Whoops, that got broken with a recent update. I’ll make a note and push out a fix as soon as I can.
The Real Person!
The Real Person!
This is fixed now in the latest versions available on TechNet or Github.
Hi Paul,
Great Script!
Is it possible in version 1.10 to get the number of messages in the Queue in the e-mail report?
The Real Person!
The Real Person!
Sure thing. Just pushed an update to TechNet and Github to include that change.
Thanks for your support 🙂
Paul-
I ran into an issue with the script I wanted to let you know about.
I was running this against my new 2013 environment and it was not detecting my LAG copies correctly. I traced it down to line 1326. if ($replaylagcopy.Key -eq $mailboxserver)
What I found is that in my environment it was having an issue due to case sensitivity. I changed the -eq to a -match and it resolved the issue.
The Real Person!
The Real Person!
Thanks, will test and update the script for that bug.
Paul,
I downloaded the script and am running on my Exchange server via windows powershell. I am using the -reportmode $true and I get an error that says “The operation couldn’t be performed because object ‘True’ couldn’t be found on “my domain controller”. Any ideas? My DC’s are Server Core.
Nevermind..I see now you don’t need $true. Saw youtube video of this script being run and that was included.
I’d like express a little frustration at your comment in the script that “reportfile implies reportmode:$true”. After chasing for an hour or two why no file was being created, I decided to add -reportmode in addition to -reportfile parameter and suddenly the file is being created.
TL;DR: -reportfile DOES NOT IMPLY -reportmode, despite documentation to the contrary. *shakes fist*
As for the command I am using, “-Command .Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail”
Paul,
Awesome that answered my question. Thank you very much!
The script runs flawlessly in powershell and everything is passed or success, but I am not able to find the outputted .HTML file. Nor is it sending an email to the address I inserted. The relay is working without any issues, any ideas?
It looks like there are parameters that are set to false,
——————————————-
[CmdletBinding()]
param (
[Parameter( Mandatory=$false)]
[string]$Server,
[Parameter( Mandatory=$false)]
[string]$ServerList,
[Parameter( Mandatory=$false)]
[string]$ReportFile=”exchangeserverhealth.html”,
[Parameter( Mandatory=$false)]
[switch]$ReportMode,
[Parameter( Mandatory=$false)]
[switch]$SendEmail,
[Parameter( Mandatory=$false)]
[switch]$AlertsOnly,
[Parameter( Mandatory=$false)]
[switch]$Log
)
———————————————
Is this what I need to change in order for this to work?
The Real Person!
The Real Person!
Mandatory=$false just means that they don’t need to be specified for the script to run.
What is the exact command you’re running?
I am just running the script but my question is if I want this to push out the HTML file does something need to be modified or is the script doing this by default? Also I need it to send out the email in which I already added the smtp settings including testing via telnet.
The Real Person!
The Real Person!
The script has multiple parameters/switches that are used to control the behaviour and output.
The script also has built-in help. So you can run this command to see some examples of how to use the different parameters:
[PS] C:Scripts>get-help .Test-ExchangeServerHealth.ps1 -Examples
So if you want it to output both the HTML file and send the email, you would run:
C:Scripts>.Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
Trying to download the script, but taken to my member content page and never gets me to the script download page.
The Real Person!
The Real Person!
I don’t see any registered users in the member site matching the email you’ve used with your comment. Use the contact form here if you need further assistance:
https://www.practical365.com/contact
Hi where do we download this script I cannot find the link anywhere
thanks
Thank you for your script.
I have a little bug on the report. I run this report from Exch 2013 MBx server. So this server mail flow test always be failed.
I replace the following line in the script to solve this problem:
$result = Invoke-Command -Session $session {Test-Mailflow} -ErrorAction STOP
with:
if ($env:computername -like $e15mailboxserver)
{$result = Test-Mailflow -ErrorAction STOP}
else {$result = Invoke-Command -Session $session {Test-Mailflow} -ErrorAction STOP}
Regards,
This fixed mt problem with Mail Flow tests failing. Thanks
This fixed my problem with Mail Flow tests failing. Thanks
Hi Paul,
Thank you for the awesome script, but I was trying to send the report to multiple recipient but get is not sending , it is sending to only one address , I have tried putting , as well as ; ..any help would be appreciated..
Amar
The Real Person!
The Real Person!
Try sending it to a distribution group. That way you don’t need to modify the script any time a recipient needs to be added or removed, you can just do it in the group membership.
I am in the process of migrating from 2010 to 2013. When I run the script on a system with the 2013 management tools it dies with the error: “Could not load file or assembly ‘Microsoft.Exchange.Data, Version=14.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ or one of its dependencies. The system
cannot find the file specified.”
The error happens at line 1159: $tmpdags = @(Get-DatabaseAvailabilityGroup -Status)
I currently have two DAGs. An Exchange 2010 and an Exchange 2013. The (Get-DatabaseAvailabilityGroup -Status) command works but the (Get-DatabaseAvailabilityGroup -Status) command gives the error. I can run the command without the -Status parameter just fine.
If I run the same script on a system with the 2010 tools installed it grabs the 2010 Dag just fine.
Thanks,
Adam
The Real Person!
The Real Person!
Some bugs with the script like that seem to pop up in co-existence scenarios.
Paul, I was able to get this working with *very* little effort in my Exchange 2010 environment. Although I already have other monitoring tools in place, this handy little script will give me additional peace of mind. I even got it running as a task from my local Win7 workstation with no errors.
If anyone cares, my task was setup like many others, except I omitted the path in the argument by simply specifying the “Start in” folder. My Arguments looked like this:
-Command .Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
Hi Paul,
These scripts are awesome and the results have impressed the right people in the places I have used them.
I have been asked if it is possible to get the results in an xml format so they can be used in a system dashboard.
Can you give me any pointers on adding thast to the script as my powershell isn’t that good yet
TIA
Andy
The Real Person!
The Real Person!
I’ve never tried XML output for the report. I suspect it won’t easily work because so much of the code is spitting out bits of HTML code that get assembled into the final report.
Hi, I’m looking for a script that would automatically run the following tests. All in one.
Test-Servicehealth
Test-ReplicationHealth
Test-Mailflow
Get-MailboxDatabaseCopyStatus
Test-MapiConnectivity
The Real Person!
The Real Person!
Sure. Have you looked at the script mentioned in the article above?
Where is the link to download the script(s). If no link how I am able to get it?
The Real Person!
The Real Person!
Yellow box at the end of the article.
Pingback: PUMA Evospeed
Hi
Where can I download this script from… cant find the download button
Hi, when I run this script on one of my exchange server i get that the Tcp listener failed, but when I use the script on another server it says that there is nothing wrong with the tcp listener on the first server.
is this something in the script or should I look elsewhere to find out why I get different results?
Steve, the script is not downloadable !
sorry – it is. rgrds.
Thank you for this Paul.
I found that the script only does MAPI test on Mailbox DBs and does not include Public Folder DBs.
In effect when you have a Mailbox Server without Mailbox DBs, only hosting PF DBs, you get an “Unknown” result in the report.
I modified the script to include PF DBs in the MAPI Test.
———-
####Combined the two arrays into one####
[array]$totaldbs = $pfdbs + $mbdbs
———-
Then in the MAPI Test Loop
———-
Instead of the original:
foreach ($db in $mbdbs)
I changed it to:
foreach ($db in $totaldbs)
———-
When I run the test-exchangehealth.ps1 script on Exchange 2013 in co-existence with 2007 I get an error
EXCH002FP – Hub Transport Server Role required services not running. (this is an exchange 2007 server with both CAS and Hub transports roles)
When I run the test-exchangehealth.ps1 script manually and send email all works apart from the above , however when I use task scheduler to run the script and send email I get MAPI test failed on all servers that do hold active DB. (But works if I run manually)
• EXCH003FP – MAPI tests failed.
• EXCH004FP – MAPI tests failed.
• EXCH010FP – MAPI tests failed.
• EXCH011FP – MAPI tests failed.
• EXCH020FP – MAPI tests failed.
Did you find any solution for the MAPI tests failed?
Pingback: having water hard
Pingback: Test-ExchangeServerHealth.ps1 v1.10 is Now Available
Pingback: Exchange 2013 PowerShell Scripts – A Practical Guide | Just A UC Guy
Thank you very much for the script. It saved me a lot of time trying to come up with a less robust solution on my own.
After quite some digging I found the two pain points that I was having with the scripts. I did not want an email on uptime errors or database preference errors. Line numbers are not exact because I added some comments and set some variables to $true so I wouldn’t have to remember switches. I am using v1.09 of the scripts.
Somewhere around line number 771 I modified the line for Uptime :
Switch ($uptime -gt 23) {
For my purposes I changed 23 to 1. I also modified the error message lines that followed in the next couple lines for completeness.
Somewhere around line number 1594 I modified the line for DB Preferences :
$dagsummary += “$($line.Database) – $string62 $($line.Preference)”
For my purposes I commented this line out so it would not trigger an email when the database was not active on the preferred server.
The Real Person!
The Real Person!
Always great to hear people are successfully customizing the script for their own needs 🙂
Hey Paul!
We’ve been having issues with our Exchange 2010 server and I was VERY thankful to find your script here to help troubleshoot and check the health of our DBs. I’m not much a script guy, but I changed the email parameters, ran the script and when it gets to “mail flow check”, the script seems to stop (the PS window closes). Does that mean the script is not completing? I’m not receiving emails or seeing a file generated either way.
Any help would be great appreciated!
Thanks!
Gary
You may send me that piece of code you changed for review rosario-dot-carco{at}fhnw-dot-ch
The Real Person!
The Real Person!
Gary, the window closes? If you’re running the script from a PowerShell window it should remain open and display any error that is causing the script to halt. Are you running it some other way?
Otherwise, run it with the -Log parameter, which will write a log file that may assist with troubleshooting.
Hey Paul!
I got it working! I was right-clicking the file and selecting “run with Powershell”. Maybe it didn’t like that. I ran directly from PS and it completed fine.
I can’t seem to get the email portion working. I set the parameters with all of our SMTP settings, but get nothing. I’ll have to review the notes again, but where is the parameter to just write an output file to the C Drive?
Thanks!
Gary
The Real Person!
The Real Person!
You’ll find all the instructions and an FAQ on the page where the script is downloaded.
Pingback: Test-ExchangeServerHealth.ps1 v1.09 is Now Available
Hi @ll,
at the moment im having problem with our Exchange 2013 and the mailflow test. Powershell tells me that there is a problem mit WIN-RM and negotiate Authentication.
Another problem is on line 408 sign 19: Remove-PSSession $session.Id is not found. Is the variable defined somewhere?
I am using Windows Server 2012 R2 in german with Exchange 2013 SP1.
THX.
Hi again,
yesterday i tried to run the script on the CAS and not on the Mailboxserver. Now it is running without any Errors.
On all my Exchange 2010 Servers i have to run the script on the Mailboxrole. Can someone explain this?
THX
André
As I told above, I scheduled the script to run on a CAS-Server, no problems. As I am developing another script, yesterday I tried to load the PSSnapin as Paul does to execute the exchange powershell commands from my Win7 Workstation and it quit with the Error “SnapIn could not be loaded”. So I do also wonder how much of the exchange powershell must be installed on my remote workstation, or whether we could get everything without installing any tools by opening a remote-powerShell-Session like this:
$s = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://phx-ex01.exchangelab.com/PowerShell/ -Authentication Kerberos -Credential (Get-Credential)
Import-PSSession $s
Of course this would only be a solution for interactive development. For scheduled execution during night, it may in any case be better to let the scripts run directly on the CAS-Servers where the needed user privileges are set up in the schedule itself (no need to ask for credentials)
Rosario
Hey Paul,
Im getting the following error from one of my cas servers… other cas server works fine…
Send-MailMessage : The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated
Ive checked permissions on all the connectors, tried using ssl and forcing credentials… any ideas?
Much appreciated!
The Real Person!
The Real Person!
This is covered in the FAQ for the script.
http://inside.exchangeserverpro.com/members/test-exchangeserverhealth/
Sorry! Should have looked, thanks a million Paul!!
Hi Paul,
Need your help:
1. How do I pause the script when it finished checking? It seems the window will auto close.
2. How can we send email to more recipients?
3. If I create a shortcut using this command: %SystemRoot%system32WindowsPowerShellv1.0powershell.exe -ExecutionPolicy Bypass -File “C:scriptsTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1” -ReportMode -SendEmail
The script will run just fine and I will receive the email, but in a glance at the end of the result (on the powershell window) before the window close by itself I saw some lines in red, it looks like there are some errors.
Thank you.
Hi Jimmy,
Answer1+3: At the end of the script you can add the noexit parameter e.g.
%SystemRoot%system32WindowsPowerShellv1.0powershell.exe -ExecutionPolicy Bypass -File “C:scriptsTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1″ -ReportMode -SendEmail -noexit
Also running the script directly from a powershell window (rather than the scheduled task) will give the desired result.
E.G. from powerhsell “C:scriptsTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1 -ReportMode -SendEmail ”
Answer 2:
1 option would be to just create a Distribution list on the exchange with the desired users.
The other option would be to add the accounts into the script like so:
$To = “user1@domain.com,user2@gmail.com,distrolist@domain.com”
Hope that helps,
Aidan
Hi Aidan,
Thanks for your reply.
Looks like the it works for my question 1 and 3.
But for the email I have tried with the commas, it will only send to the first recipient. I haven’t created a distribution list.
Sorry Jimmy, my bad!
I wasnt looking at the script…
Remove the To parameter from the array and below it create a variable with the smtp addresses:
Line numbers 109-116
$smtpsettings = @{
From = “exchangeserver@exchangeserverpro.net”
Subject = “Exchange Server Health Report – $now”
SmtpServer = “smtp.exchangeserverpro.net”
}
$To = “user1@domain.com”,”user2@domain.com”,”user3@domain.com”
Now add the -To parameter in the send-mailmessage function:
Line numbers 1528-1530
Send-MailMessage @smtpsettings -Body $htmlreport -BodyAsHtml -To $To -Encoding ([System.Text.Encoding]::UTF8)
That should be that!
The Real Person!
The Real Person!
Seriously, just use a distribution list. Then you don’t need to edit the script every time your list of recipients changes.
It worked for months as Paul programmed it. But for a strange reason I did not track back, it began to send the eMail only to the first person around January or February. I guess Aidans solution should be
$to = “user1@domain.com,user2@domain.com,user3@domain.com”
with only one pair of “” – Rosario
Thanks Paul & Aidan,
I have not tried Aidan’s solution yet, as I am just using the distribution list for keep the thing simple.
To wrap up at this point, my task scheduler is being used to run the script from inside a batch file. Not sure why I keep having problem running the script if I specify it directly in the task scheduler.
Also don’t forget to use @echo off at the beginning if not the task will keep running and running.
Scheduling the powershell script is a little bit tricky.
Program/Script: C:WindowsSystem32WindowsPowerShellv1.0powershell.exe
Add argument: -Command “& C:psScriptsCheckExchangeServerHealth.ps1 -sendEmail”
Start in: C:psScripts
Disregard ran this Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass and good to go. Thanks!
Paul,
When I run the script I get not digitally signed error… ***HELP*** 🙂
Pingback: leafit
Hello and thanks for another wonderful script, Paul.
Also related to the ignorelist.txt a rather silly question but one that’s vexing me: is it supposed to have any particular format or structure? Or a simple line-by-line list of servers, databases, DAG, etc?
Is there a way to limit the scope to a single AD site (or exclude others)?
Thanks so very much. You The Man, man!
The Real Person!
The Real Person!
Simple line by line list, yes.
You can customize it any way you like really. The builtin parameters provide some flexibility but everyone has different needs.
The script just uses the Exchange cmdlets. So if you want Get-ExchangeServer to return just the servers in a site, modify that line of the script accordingly.
Pingback: deckard hanrahan anxiety
Did anyone managed to migrate this wonderful script to support Exchange 2007?
Love the script, I am having one error though, it will not call the ignorelist.txt file. It says “Warning: The file at …ignorelist.txt could not be found. No servers, DAGs, or databases will be ignored.” Is there a fix for this?
Thanks.
The Real Person!
The Real Person!
The script looks for the file in the current directory. Are you running the script from the directory where it is stored, or running it from a different directory?
Pingback: Why Did My Database Failover to the Wrong Server?
Great script. Very good to show customers. They know that green is good and red is bad. Then it is easy to explain that you have to fix errors in their environment.
Thank You Paul.
The Real Person!
The Real Person!
You’re welcome. Glad you are finding it useful.
Pingback: My Favorite Scripts to Use with Exchange | Oddytee
Thanks Paul. !!!!!!!!!!!!!!!!!!
Perfect work.
Brilliant! i should have known to retrace steps… like i said before, “NEWB”
i was missing a double quote at the end of the smtp server name string!
Thanks! wish there was a way to buy you a beer or cup of coffee!
Cheers!
Joel
Paul thank you! This is probably a newb issue but i keep getting this error when i run this and cant seem to figure it out…
[PS] C:scripts>.Test-ExchangeServerHealth.ps1 -Reportmode -Sendmail
Unexpected token ‘Mailbox’ in expression or statement.
At C:scriptsTest-ExchangeServerHealth.ps1:327 char:19
+ $mbrole = “Mailbox <<<< Server Role"
+ CategoryInfo : ParserError: (Mailbox:String) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
the error refers to the section in the script where variables for the server roles are initialized, here:
# The server roles must match the role names you see when you run Test-ServiceHealth.
$casrole = "Client Access Server Role"
$htrole = "Hub Transport Server Role"
$mbrole = "Mailbox Server Role"
$umrole = "Unified Messaging Server Role"
Thank you
Joel
The Real Person!
The Real Person!
Have you modified that line at all?
Yes Paul i did but only to try and narrow down the issue. Running the script as is, with only the email settings modified, produces the same error. Sorry for the confusion. i posted the error produced when using the modified order, but posted the original code as reference. My bad!
the original code:
# The server roles must match the role names you see when you run Test-ServiceHealth.
$casrole = “Client Access Server Role”
$htrole = “Hub Transport Server Role”
$mbrole = “Mailbox Server Role”
$umrole = “Unified Messaging Server Role”
i get this error:
[PS] C:scripts>.Test-ExchangeServerHealth.ps1 -reportmode -sendmail
Unexpected token ‘Client’ in expression or statement.
At C:scriptsTest-ExchangeServerHealth.ps1:327 char:19
+ $casrole = “Client <<<.Test-ExchangeServerHealth.ps1 -Reportmode -Sendmail
Unexpected token ‘Mailbox’ in expression or statement.
At C:scriptsTest-ExchangeServerHealth.ps1:327 char:19
+ $mbrole = “Mailbox <<<< Server Role"
+ CategoryInfo : ParserError: (Mailbox:String) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
I have a Single Exchange 2010 Server SP3 (All Roles – no Unified Messaging) running on Windows Server 2008 R2 Standard SP1.
Could it be SP3?
thank you
Joel
The Real Person!
The Real Person!
The problem will most likely be where you made changes (to the SMTP settings) and haven’t closed a set of quotes properly.
I found this took quite a while to run in a larger environment, 14+ hours. I was able to cut that time down to just a few hours with modifying the Test-E15MailFlow function, line 372 to simply add the -ADPropertiesOnly flag. Running the script with -Verbose I saw this is where it was hanging up. I hope it can help others!
Write-Verbose “Creating PSSession for $e15mailboxserver”
$url = (Get-PowerShellVirtualDirectory -Server $e15mailboxserver -ADPropertiesOnly | Where {$_.Name -eq “Powershell (Default Web Site)”}).InternalURL.AbsoluteUri
The Real Person!
The Real Person!
Good catch, thanks for sharing your experience.
I have tried this on our Exchange 2010 set up. It reports a FAIL for the ‘Mailbox Server Role Services’ for one of our mailbox servers, but I’m not sure where to check why this is failing. I have looked at the script and couldn’t find out what test it is running for this. The server concerned seems to be running fine, our backup mailbox server gets a Pass for this test. A look at the logs on the server shows nothing amiss either.
What does ‘Mailbox Server Role Services’ actually test?
The Real Person!
The Real Person!
The script uses the output from Test-ServiceHealth to report the service health status.
You can run that cmdlet on its own to investigate further:
https://www.practical365.com/exchange-2013-test-service-health/
(applies to Exchange 2007/2010/2013)
Brilliant script. Thanks for the hard work you and the others put into this.
Hi Paul,
i would like to run the script as scheduled Task every morning and send the Report as mail. I want to use a dedicated taskuser that has no domainadmin rights. Which rights are necessary that the script is runninig successfull?
At the Moment i get Errors checking the mailboxservice, Transport Queue and the mail flow test. When i run the script as Domain admin everything works fine.
The Real Person!
The Real Person!
The minimum I’ve found to work is an account with Exchange Org view-only rights, local admin on each Exchange server, and also local admin on the server running the scheduled task (that last one bothers me, but I haven’t had time to work out anything different).
I tried, but stil unable to read the database mounted information and also the Transport Queue info.
Hi Paul,
thanks for your quick answer. I’ve tried to run the script as SYSTEM on the Exchange Servers. On most of the Systems it’s running (Exchange 2010), only on 1 Exchange 2007 Server it won’t. I gave the taskuser Organization Management and Server Management and local admin on the Exchange Server and it is running now.
We have found a Problem with line 275: [int]$uptime = “{0:N0}” -f $uptime
When the line is commented out the uptime is shown correctly. If the line is active the uptime is always shown with 2 hours. Maybe this behavior is because we use german OS?!
So far everything works fine. Great Script.
Greetings
André
Dear André, I work at the FHNW but we run the servers in english, never in german. But I had the same problem and Simon, Oleg and Andrew already documented the issue here. I did it too and wrote these lines in one of my previous posts:
$uptime = [math]::round((New-TimeSpan $laststart $now).TotalHours,0) #Cr: rounded instead of int truncation
#Cr: removed to avoid string and int conversion/display problems: [int]$uptime = “{0:N0}” -f $uptime
#Cr: this could also be a fix, coming from Paul himself:
#$timespan = (New-TimeSpan $laststart $now)
#[int]$uptime = “{0:00}” -f $timespan.TotalHours
Dear Rosario,
thanks for your Response.
I work at a Application Service Provider with many different customers. So we have to take what we get 🙂 , German, Englisch, Nederlands and else.
It was not a big Problem for us. After we commented out the line everything works fine und the uptime is shown correctly.
Many Greetings from Germany.
André
The Real Person!
The Real Person!
Download the latest script version (v1.07), it includes a fix for that uptime bug as well as localization strings for non-English systems.
Hi Paul,
I am getting an error ” Write-Error : The operation couldn’t be performed because object ‘True’ couldn’t be found on ‘DC.xxxx
.prd’.
At C:scriptsExchangeTest-ExchangeServerHealth.ps1:479 char:14
+ Write-Error <<<< $_.Exception.Message
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Microsoft.PowerShell.Commands.WriteErr
orCommand"
Please help.
The Real Person!
The Real Person!
What is the exact command you’re running?
Hi Paul,
I am using ” .Test-ExchangeServerHealth.ps1 -ReportMode $true -SendEmail $true “
Hi Paul,
It’s working, Thanks for the Great Script.
The Real Person!
The Real Person!
No need for the two $true’s there.
Thanks Paul
Pingback: Exchange Health Check Steps | Chase's Notes
Nice script. Good job! Thank you Paul
And again in large environment quite time consuming.
Modification only in one line saved more than 1 hour in my case.
From: [array]$activedbs = @(Get-MailboxDatabase -status | Where {$_.MountedOnServer -eq ($server.fqdn)})
To: [array]$activedbs = @(Get-MailboxDatabase -status -Server $server | Where {$_.MountedOnServer -eq ($server.fqdn)})
That’s true. I noticed great speed improvements when executing exchange power-shell cmdlets simply by indicating, e.g. a specific Active Directory Domain Controller to use instead of letting it blank and letting the system choose one (where applicable of course).
Hi!
Thanks for the great script!
I’m getting Failed on Mail Flow Test for the server on which I’m running the script. I have tried 3 servers with the same result. Any ideas?
/Henrik
PowerShell Scripts
Access the script files and additional usage guidance.
Test-ExchangeServerHealth.ps1 Script
Get-DAGHealth.ps1 Script
Get-MailboxReport.ps1 Script
Get-DailyBackupAlerts.ps1 Script
On this page there is not download option: However it does ask me to join.
23770 downloads so far.
This script is available for download by Exchange Server Pro Insiders. Join here it’s free.
Looking at the code for ExchangeServerHealth code it is not the script referenced in this article. Is this article refering to Get-MailboxReport.ps1?? I can’t see any script name in the article at all, hence my confusion.
I have signed up, why does it still request i ‘join up’ to download this script?
The Real Person!
The Real Person!
After joining you can login to the members area to access the scripts.
http://inside.exchangeserverpro.com/members
I only see 4 scripts. Is that all the content there is?
The Real Person!
The Real Person!
At the moment the insider access gets you 4 scripts and 1 free ebook. The next planned addition is the Exchange 2013 Boot Camp videos that I’m working on.
How do I get access to more scripts? I am interested in the exchange backup reporting and this script.
The Real Person!
The Real Person!
The Get-DailyBackupAlerts.ps1 script is available on the same members page.
Pingback: Test-ExchangeServerHealth.ps1 V1.07 Released
Pingback: Exchange 2010 Health Report | All Things Exchange
Paul,
Great work, thank you.
I have one question about version 1.06. In an earlier version I was able to exit out before it sent the report if there were no failures. Is it possible in this version? We manage several Exchange environments where we schedule it to run every 30 minutes and only want the report when there is a failure.
The Real Person!
The Real Person!
Using the -AlertsOnly switch will suppress the email unless there is a warning or error to report.
The Real Person!
The Real Person!
V1.06 has just been released
https://www.practical365.com/test-exchangeserverhealth-ps1-v1-06-now-available/
Paul,
Thank you!
Beta Version – all is OK! Great Work!
The Real Person!
The Real Person!
Thanks for letting me know 🙂
Hi
I try to run the script but after sometime I received the following error
Write-Error : The operation couldn’t be performed because object ‘True’ couldn’t be found on XXXXXXXX (DC)
‘.
At C:UsersXXXXXXDesktopTest-ExchangeServerHealth.ps1:401 char:14
+ Write-Error <<<< $_.Exception.Message
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Microsoft.PowerShell.Commands.WriteErr
orCommand
The Real Person!
The Real Person!
What is the full command that you’re running?
.Test-ExchangeServerHealth.ps1 -ReportMode $true
The Real Person!
The Real Person!
Ok. Please double check the help info included with the script. Correct syntax is:
.Test-ExchangeServerHealth.ps1 -ReportMode
TO:
[int]$uptime = (New-TimeSpan $laststart $now).TotalHours
[int]$uptime = “{0:N0}” -f $uptime
The Real Person!
The Real Person!
I have a fix coming in the next version. In the meantime try changing those lines to:
$timespan = (New-TimeSpan $laststart $now)
[int]$uptime = “{0:00}” -f $timespan.TotalHours
As I had a display-Problem, this is what I did in the version of the script I downloaded from here
#[int]$uptime = (New-TimeSpan $laststart $now).TotalHours
#[int]$uptime = “{0:N0}” -f $uptime
#Cr: changed the above two lines as following:
$uptime = [math]::round((New-TimeSpan $laststart $now).TotalHours,0) #Cr: rounded instead of int truncation
#Cr: removed to avoid string and int conversion/display problems: [int]$uptime = “{0:N0}” -f $uptime
The Real Person!
The Real Person!
Glad you’ve worked out a fix. I’ve got a different fix coming in the next version of the script which I hope to release very soon. Hopefully that also works for you 🙂
Hi Again Paul,
I found how to fix:
Changed lines 615,616
From:
[int]$timespan = (New-TimeSpan $laststart $now).TotalHours
[int]$uptime = “{0:N0}” -f $timespan
TO:
[int]uptime = (New-TimeSpan $laststart $now).TotalHours
[int]$uptime = “{0:N0}” -f uptime
And now all information are correct in report!
Thanks!
Hi Paul,
I have a problem with last version of your script:
Uptime (hrs): Cannot convert value “1 341” to type “System.Int32”. Error: “Input string was not in a correct format.”
At C:ScriptsServerHealthTest-ExchangeServerHealth.ps1:616 char:17
+ [int]$uptime <<<< = "{0:N0}" -f $timespan
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
—
As i can see – this happens only on servers with uptime more than 1000 hours – may be because it is reporting time with space: 1(space here)341 hours
How can i fix it ?
Thanks again for this mega script!
Thanks Paul it’s working.
Hi Paul,
i have run this script on exchange server 2010 and in our environment we have exchange 2003 also.
so i want to ignore ex 2003 server and i have mention server name in ignorelist.txt file as per like below.
“test1″,”test2″,”test” etc.
but after that when i run this script it’s don’t ignore this server.
can you help please where i am wrong and give me exact direction how i should write name in txt file.
Regards,
Atul
The Real Person!
The Real Person!
Place the server names in the ignorelist on one line each, eg
server1
server2
server3
Hi Paul,
Very nice script and it helped me to get check the status daily morning.
I have scheduled the script in windows server 2008 where management tools installed and it is running fine.
Now i am planing to decommission the server so i have scheduled the same script in one of the CAS server.
i am getting correct result for all other exchange servers’ health but for the server from where task schedule configured i am getting – Client Access Server Role required services not running.
I have tested the script from manually running it and no errors reported. But if i run the schedule task i am getting services error for that specific exchange server from where i ran the schedule.
I don’t have any clue why this is happening.
Could you please help me..
Dear Paul,
Can we please add white space, Free DB disk space and Free Log Disk space free in the next release.
Regards
Sanju,
Steve Goodman has written an Exchange Environment Report script that pulls that information and has been updated to support Exchange 2013. You can download the script here:
http://www.stevieg.org/2011/06/exchange-environment-report/
Paul also endorses this script:
https://www.practical365.com/generate-html-report-exchange-2010-environment/
I did it in my version. Unfortunately you have a lot of lines to add to generate the whole tables for output. I am out for vacations but I can send you my version if you like by eMail.
We are Exchange 2007 SP3 (CCR)… when i run the script it comes with warning as below:
WARNING: The Windows PowerShell snap-in
‘Microsoft.Exchange.Management.PowerShell.E2010’ is not installed on this
machine.
tried below link still the same:
http://thwack.solarwinds.com/thread/58501.
plz help
The Real Person!
The Real Person!
The script is designed for Exchange 2010 and 2013. It loads the management snapin for those versions, not for 2007.
You could replace the line in the script so that it loads the 2007 snapin instead, but you’ll run into other issues that the script simply isn’t designed to handle.
So there will be some work ahead of you to customize it for your environment. But you’re welcome to take the script and modify it however you wish.
if i am not wrong below is where i need to change…. need some help as to where and what changes to be done.
#Add Exchange 2010 snapin if not already loaded in the PowerShell session
if (!(Get-PSSnapin | where {$_.Name -eq “Microsoft.Exchange.Management.PowerShell.E2010”}))
{
Write-Verbose $initstring1
if ($Log) {Write-Logfile $initstring1}
try
{
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP
}
catch
{
#Snapin was not loaded
Write-Verbose $initstring2
if ($Log) {Write-Logfile $initstring2}
Write-Warning $_.Exception.Message
EXIT
}
. $env:ExchangeInstallPathbinRemoteExchange.ps1
Connect-ExchangeServer -auto -AllowClobber
}
The Real Person!
The Real Person!
Replace the Microsoft.Exchange.Management.PowerShell.E2010 with the name of the Exchange 2007 snapin, which I believe is Microsoft.Exchange.Management.PowerShell.Admin
Also remove these lines:
. $env:ExchangeInstallPathbinRemoteExchange.ps1
Connect-ExchangeServer -auto -AllowClobber
Pingback: Troubleshooting Microsoft Exchange Server with PowerShell
Hi Paul,
I am using the script: Test-ExchangeServerHealth.ps1
Does the above script report on the DAG Status? Because when i run it I can’t see a reference to the DAG?
Could just be me 🙂
Cheers
The Real Person!
The Real Person!
If you use the option to send an email report or output the report to a file it will include the DAG status. I’m working on adding the DAG status into the console output as well.
Hi Paul
We have been using the script successfully for a few months in a large government site.
We have some databases (mainly used for Journaling) that we want to report on (they have DAG copies), but they do not contain Content Indexes . The IndexEnabled property is set to $False. The end result is a fair bit of red in the report about both Healthy and Unheathy Content Indexes.
Rather than me butcher your elegant scripting, can you add to the wish list for future versions a capability to either list CI enablement and/or change the Healthy/Unhealthy status to indicate Not Configured (or similar) in a neutral colour.
Regards
Ray
The Real Person!
The Real Person!
Interesting. Not a scenario I’d considered. Probably won’t be too hard to account for that in a future version.
I get one more error, thats I (who is a beginner on this) dosent understand:
This I get when i start the script:
[PS] C:Script>.Test-ExchangeServerHealth.ps1 -Log -SendEmail
Initializing…
Update-TypeData : The following error occurred while loading the extended type data file:
Microsoft.PowerShell, D:Program FilesMicrosoftExchange ServerV14binexchange.types.ps1xml : File skipped because i
t was already present from “Microsoft.PowerShell”.
At D:Program FilesMicrosoftExchange ServerV14binRemoteExchange.ps1:94 char:17
+ Update-TypeData <<<< -PrependPath $typeFilePath
+ CategoryInfo : InvalidOperation: (:) [Update-TypeData], RuntimeException
+ FullyQualifiedErrorId : TypesXmlUpdateException,Microsoft.PowerShell.Commands.UpdateTypeDataCommand
Update-TypeData : The following error occurred while loading the extended type data file:
Microsoft.PowerShell, D:Program FilesMicrosoftExchange ServerV14binExchange.partial.Types.ps1xml : File skipped b
ecause it was already present from "Microsoft.PowerShell".
Microsoft.PowerShell, D:Program FilesMicrosoftExchange ServerV14binexchange.types.ps1xml : File skipped because i
t was already present from "Microsoft.PowerShell".
At D:Program FilesMicrosoftExchange ServerV14binRemoteExchange.ps1:104 char:16
+ Update-TypeData <<<< -PrependPath $partialTypeFile
+ CategoryInfo : InvalidOperation: (:) [Update-TypeData], RuntimeException
+ FullyQualifiedErrorId : TypesXmlUpdateException,Microsoft.PowerShell.Commands.UpdateTypeDataCommand
The Real Person!
The Real Person!
You can ignore that one.
When running the script with modifyed smtp settings i get this:
Send-MailMessage : The specified string is not in the form required for an e-mail address.
At C:ScriptTest-ExchangeServerHealth.ps1:1825 char:20
+ Send-MailMessage <<<< @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF
8)
+ CategoryInfo : InvalidType: (Exchange server ADMIN:String) [Send-MailMessage], FormatException
+ FullyQualifiedErrorId : FormatException,Microsoft.PowerShell.Commands.SendMailMessage
The Real Person!
The Real Person!
“The specified string is not in the form required for an e-mail address.”
You should double check the email address you’re trying to use.
Thanks, my fault, the from adress was wrong.
W’ve been using this for some months now- great script. We had an issue over the weekend where a mailbox server manually had the exchange services stopped and then was shutdown. However the windows failover clustering service was not stopped and (I think) because the server was shutdown before this service realised the services were gone, the failover did not happen.
What this made us realise is that even though clustering is a windows server service- its a fairly critical part of a DAG and it would be nice to monitor the service’s availability. Practical or a folly?
We monitor that, but in real-time as part of our network monitoring setup. We only run this script in the morning, as Paul says – to identify overnight issues – and then once more in the afternoon.
If key windows services fail on a server, we prefer to know about it immediately rather than waiting for the scheduled task running this (awesome) script.
(we’re using IPMonitor from Solarwinds).
Cheers Shane.
yep we should be doing that also….but working in a govt dept these things take too long. So we tend to monitor our own to make sure. However I’m putting the request in with the relevant area
Hi,
Don’t know what I am doing wrong but I don’t get any html output, if I export it to an html file it opens an empty web file. I tried both via the command line and task sceduler. the email is beeing send to me but I only see; “Exchange Server Database Availability Group health check results as of dinsdag 27 augustus 2013 17:14:12”
Only thing I changed are the mailsettings.
Anybody a clue?
Command; -command c:scriptsGet-DAGHealth.ps1 -detailed -sendemail
I run it from my only exch2010 server.
the script Get-DailyBackupResults.ps1 works fine though..
Get an nice report in my mailbox.
Hi Paul,
I was modifying the Script and want to add RPC connection test.
# Start RPC Connections Test
if ($IsCAS)
{
$RPC = $null
$RPC = Get-Counter “MSExchange RPCClientAccessConnection Count” | select -expandproperty CounterSamples | select CookedValue
$serverObj | Add-Member NoteProperty -Name “RPC Connections” -Value $RPC -Force
if ($Log) {Write-Logfile “RPC Connections is $RPC”}
}
#END – RPC Connections Test
However the above does not works and errors out
The Real Person!
The Real Person!
What error message?
Thanks for the script though
There is no output on shell and i f I use the same code as in transport queue it gives out the queue length. I will get back to office and share the correct output
Paul, thanks for your effort in producing this script, I enjoyed seeing Green across the board! 🙂
Brilliant job and very much appreciated!
Pingback: Test-ExchangeServerHealth.ps1 v1.04 Released
Love the script. Love seeing all of the GREEN font. However, I received one big red FAILURE on one test on one of the servers. It was the test-mailflow cmd. Everything else was green. All services were running. Test-MAPIConnectivity. But not test-mailflow. Test-mailflow from other server, even in the other datacenter, to the subject servers succeeds. But test-mailflow from the subject server, even to itself. I can’t find much on troubleshooting this event. Do you have any suggestions? Can the system mailbox be reset somehow? I’m at a loss as to how to best deal with this failure.
Thanks
Never mind. Found it. Turned out to be a duplicate system mailbox in AD. Had the same GUID, but was appended with “CNF:” and another GUID. Microsoft said it was near impossible for this situation to occur. Guess I just got lucky. I deleted the duplicate System mailbox. All is good now. Thanks.
Pingback: Test-MailboxServer - Health Check an Exchange 2010 Mailbox Server
Paul you are a legend! Really appreciate the help 🙂
Keep up the great work!!
Hi Paul,
Whats the best way to exclude the Edgetransport service from being listed your array ? I love the script but dont want to start sending it to my team with big red markers saying service Failure when we arent using it 🙂
P.S. I have zero powershell experience but getting into thanks to this 🙂
Appreciate any help!!!
Kind regards,
Aidan
The Real Person!
The Real Person!
If you mean the Edgesync service on Hub Transport servers, then the solution is to set the service to Automatic startup and start it.
Hi Paul,
You are correct but the service will not start as we are not using it. I can see in your other article relating to the event ID 1045 (which I receive when trying to start it) the solution is to create the configuration object New-EdgeSyncServiceConfig -Site “my site”
Are there any implications to be aware of or prior criteria?
Appreciate the help!!
Kind regards,
Aidan
I should also probably mention its a 2 CAS and 2 DAG server array we use with cisco ironports in front to handle antispam etc..
The Real Person!
The Real Person!
No implications that I’m aware of. The test cmdlet expects the service to be running, and I’ve always had it running even when no Edge servers are present.
Pingback: Step by Step: How to perform Exchange 2010 Maintenance and Testing « The Life Strategist
Hello Paul,
We have 6 exchange servers in the same site with typical exchange installation i.e. Hub, ,Mailbox and CAS.
For Example below are the exchange servers:
mailmxexch01
mailmxexch02
mailmxexch03
mailmxexch04
mailmxexch05
mailmxexch06
i ran the below script on mailmxexch06 exchange server
.Test-ExchangeHealth2.ps1 –reportmode $true –reportfile ServiceHealthStatus.html
result is generated in ServiceHealthStatus.html file .
My question 1 : If i run the above mentioned script on mailmxexch06 exchange server , what will be the source server for mail flow?
IF the source server is mailmxech06 (where i am executing the script) then what will be the sending email addres and recipient email address for the mail flow test?
My second question 2: is this script is for both inbound mail flow test as well as for outbound mailflow test? OR this test only for outbound? .
Question 3: How is the test for the mailflow performed?
protocol logging is enabled on the above all 6 servers , i didnt found any SMTP Send OR Recieve logs?
Question 4: To send a test email from source server to target server , we need sender and recipient email address right? what wll be the sender/recipient email addresses in the above script?
please suggest me.
Is there any way to remove a specific role from the list. We dont have any Unified Messaging Servers in our org and I’d like to remove it from the report.
The Real Person!
The Real Person!
Sure. Open the script in a PowerShell editor and remove those parts from the report section.
I found the cluster problem. It was a rogue network with only IPv6 addresses created by the new NICs before addressing. The other issue is a DNS problem where the A record is disappearing. I really appreciate this script and all the other things you do for the Exchange community.
I’ve been running the script for a while now and love the latest version. I recently changed nics in my server to vmxnet 3 and they all seem to be running fine. When I run the script at the command prompt all servers tests pass as well as the DAG tests. When I run it as a scheduled task and send email I get the following error on one of the HT/CAS boxes: “Could not test service health”. This occurs in all four columns regarding roles. Any idea why?
Both tests, command line and scheduled, report that the cluster network for each of my three mailbox servers has failed. However, the cluster appears fine in the console and databases can be moved at will. Any idea why this would be marked as failed?
I might be a bit late, but I just integrated some new figures into the script:
– local Drives: Capacity, Used, Free Space
– Mount Points: our DBs are directly attached via SAN now, so again, MountPoint Name, Capacity, Used, Free Space
– DB statistics: DB Size, Number of Mailboxes, Mailbox Average Size, WhiteSpace in DB, Date of last FullBackup
Paul, thanks a lot, I learned a lot, Rosario
how you did that how added drive size in the script
Rosario,
Can you please give us the enhanced changes which you added ?
Hi,
You can set forwarding on mailbox that is mentioned in the script.
Just a workaround.
Thanks for the script. however what is the parameter if want to send report to multiple recipients?
The Real Person!
The Real Person!
You can set mutliple recipients in the SMTP config in the script separating them with a comma.
To = “email1@domain.com”,”email2@domain.com”
Or just put a single address that goes to a distribution list.
Paul,
I’ve tried what you’ve suggested and that does not work for me, it only sends to the first email address. Could you help out?
Thanks
Paul,
Please ignore my previous comment, I was been a complete idiot, I found the problem.
Love this script. Thanks Paul!
Hi Paul,
thank you for the great script.
I am facing a strange issue here. When I run the script , no matter if i use server, server list or no parameter at all…. After displaying status of servers in my site, it automatically starts checking the servers in a remote site, which I obviously dont want to do. Could you please let me know what could be triggering this?
Also, I used ignorelist parameter as well . but it didnt work.
This is causing my script to pause for good 5 mins before displaying error that cannot connect to those servers.
Any help would be much appreciated. Thanks
The Real Person!
The Real Person!
Probably a bug, I will try and identify it.
Hi Paul,
the script working fine. I’m trying to run this script in my task scheduler with a service account which have minimum priviliage on the server. For example, i want the service account able to complete the test and send the report out but unable to make any changes to Exchange or server and reboot/shutdown server. Do you have any suggestion on which kind of membership I should give to the service account ?
Hi Paul,
Any suggestion on the rights?
The Real Person!
The Real Person!
There’s been some recent discussion of it further down the comments here:
https://www.practical365.com/powershell-script-health-check-report-exchange-2010/#comment-31874
Pingback: The Whiteboard | Exchange 2010: Powershell health script
Hi Paul,
Any news on uptime check issue?
Regards,
JP
Heya Paul,
thanks for the script – nice work.
Just one issue. I’ve had v1.1 working fine and have now upgraded to v1.2. Strangely enough I’m wrestling with permissions issues now. I am running with a domain service account which has “log on as a batch job” to the local server. However it refuses to run unless I make it a local Administrator of the machine. The task does not error, it just runs perpetually.
If I remove the following line, it works (but then does not report on any DAG checks):
. $env:ExchangeInstallPathbinRemoteExchange.ps1
Any suggestions? (Exchange 2010)
Cheers,
Rhys
The Real Person!
The Real Person!
I’ve noticed the same issue myself but haven’t had a chance to look into it yet.
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
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,
Currently we are running same script to export health of our exchange servers, Script is working ok..
thanks for nice work.
But My question is that can we exclude Database name instead of server name.?
I am just checking if you have any alternate way to do this please help me.
Thanks,
Sushant
Hi! First I’d like to say this script looks fantastic and I’d love to get it running. Can this script work in a Exchange 2007 only environment?
We have a CCR and 2 HT/CAS/MBX servers, and another CAS
When I attempt to run it, I get the following:
—— Checking EXCHE
DNS Check: Pass
Server up: Pass
Uptime (hrs): 352
Server version: Exchange 2007
Roles: Mailbox, Client Access, HubTransport
Then it pauses there for a moment and the window just closes. This happens in Powershell, Exchange Management Shell, or Powershell Editor. I can’t seem to find why it’s closing and if it’s an error in the script or something else. Any help would be greatly appreciated.
Thank you!
As an added note, it completely shuts down during the General Server Health Check.
Hello Hayley,
Wooten mentioned
“Figured I would reply so others could fix it in 2007. I got it working using the following old script on 2007, just change the 2010 plugin to the 2007 plugin, comment out the 2010 Get-AD stuff, and add-in your smtp settings and you’re done.
http://dl.dropboxusercontent.com/u/13009245/facility.net/Test-ExchangeServerHealth.ps1
Also if anyone wants to setup scheduled task for this I got it working as well by created a batch file with the following code:
powershell.exe -command “. C:ScriptsExchangeServerHealthTest-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true”
btw, We are working to add “Test-OWAConnectivity” and ‘Test-Activesyncconnectivity” tests as well to the script for Exchange 2007. I’ll share it once completed.
Hi Sanjeev,
I figured out the exact area that was causing that issue. I’d already changed the snapping to be for 2007. The section that runs the ping check apparently crashes the script. I don’t know why, but as soon as I removed the section, the script ran flawlessly. I left in the part about new object and the write host for a pass. This way it just registers the ping as a pass and moves on. If the servers aren’t pinging, I’ll know about it before then. It has to be in the script or the report ends up being skewed. Thank you for your help!
Hi,
First – thank for that script. Extremly usefull. 🙂
When I call that script from another (to get any “documentation snapshot” of env) I receive something like that:
—- Database Copy Health Summary —-
out-lineoutput : The object of type “Microsoft.PowerShell.Commands.Internal.Format.FormatStartData” is not valid or not in the correct sequence. This is likely caused by a user-sp
ecified “format-table” command which is conflicting with the default formatting.
+ CategoryInfo : InvalidData: (:) [out-lineoutput], InvalidOperationException
+ FullyQualifiedErrorId : ConsoleLineOutputOutOfSequencePacket,Microsoft.PowerShell.Commands.OutLineOutputCommand
In script before call Test-ExchangeServerHealth.ps1 I’ve only mkdir $repdir.
Have You any idea how to fix it?
Temporary workaourd (which works) is call Test-ExchangeServerHealth.ps1 into variable (also call mkdir into variable works). Or modify 6 lines starting from $dagdatabasesummary | ft (ie. by remove ft or comment that output — which is aceptable if we execute it for HTML/mail report).
But it’s quite annoying. 🙂
The Real Person!
The Real Person!
Yes, those 6 lines you refer to make the script a bit awkward for what you’re trying to do I’d say. Removing them is fine if you just want the HTML output.
Hi,
Nice script!!
But could you please clarify what does mean status:
– Mailbox Server Role required services not running.
– Client Access Server Role required services not running.
– Hub Transport Server Role required services not running.
For one of the node in DAG cluster. Cluster is up and running. What should I check in this case?
Thank you!
The Real Person!
The Real Person!
Use Test-ServiceHealth to identify which service isn’t running.
Paul, Your script is an amazing tool. I would like to send a copy of the HTML report to Share Point instead of the default location. Could you tell me where to set an alternate directory?
Thank you!
Hi,
The scripts run’s successfully but does not generate any report…
got it.
We had an issue last night where our deployment scripts failed to set the http redirect for OWA for some new CAS servers we built. Is there a way to build this into the next version?
CHeers
Tony
The Real Person!
The Real Person!
I have no plans at this stage to add anything that *changes* configurations.
G’day Paul,
In the earlier versions of this script, it didn’t seem to cope well if it had been run more than once within a short amount of time.
With that in mind, can this new version of the script be run at the exact same time on two separate nodes?
Y’see, we have the script in place and fully configured to run on two of our HUB nodes, so that if one has a Transport failure, at least we’re still able to get reports and/or alerts from an alternative node with accurate health information.
What I want to do is set up the “alerts” version of the script to run to the exact same schedule on two nodes every ten minutes.
Then I want the “health report ” version to run to a staggered schedule across both nodes, thus delivering health reports every three hours from a different node each time.
But what I don’t want to do is lull myself into a sense of false security thinking the alert scripts are happliy running every ten minutes, when in fact they’re failing, because I’m trying to run them simultaneously.
I’ve run some tests, and the scripts seems to be coping with running simultaneously on two nodes, but I just thought it wise to check.
Kerry
The Real Person!
The Real Person!
I can’t think of any reason why it would not work if two servers were running the check simultaneously or within a short period of time.
Paul! AWESOME script made even better. You ROCK!
We have a Lagged DAG in a separate Data Center which was causing failures when performing the Test-ReplicationHealth check, specifically the DBLogReplayKeepingUp health check. In order to repair I created a new variable:
$transientevsupptimeout = 5 #Change to set the TransientEventSuppressionWindow in minutes for test-replicationhealth
Then modified line (876 in the original script):
$replicationhealth = $dagmember | Invoke-Command {Test-ReplicationHealth -TransientEventSuppressionWindow $transientevsupptimeout}
This reduces the number of failures due to transient load generation.
http://technet.microsoft.com/en-us/library/bb691314(v=exchg.141).aspx
Now the script runs error free.
Figured it out… Both the command prompt (cmd.exe) and the Task Scheduler do NOT like the quotes around the command.
powershell.exe -command E:PowerShellScriptsExchangeServerHealthTest-ExchangeServerHealth.ps1 -reportmode -sendemail
Strip them off, and voila. It’s working!
Thank-you for your help
Hi Again,
Just triple checked.
If I run the following command in the command prompt (cmd.exe) it does not work and throws the error I posted earlier.
If I run it from the powershell (fresh, just open and run) it works like it should.
powershell.exe -command “E:PowerShellScriptsExchangeServerHealthTest-ExchangeServerHealth.ps1 -reportmode -sendemail”
It doesn’t like the “sendemail” parameter for some reason
Here’s what I get when i run it from the command line!
C:Usersexchadmin>powershell.exe -command “E:PowerShellScriptsExchangeServerH
ealthTest-ExchangeServerHealth.ps1 -reportmode -sendemail”
E:PowerShellScriptsExchangeServerHealthTest-ExchangeServerHealth.ps1 : A par
ameter cannot be found that matches parameter name ‘sendemail”‘.
At line:1 char:96
+ E:PowerShellScriptsExchangeServerHealthTest-ExchangeServerHealth.ps1 -repo
rtmode -sendemail” <<<<
+ CategoryInfo : InvalidArgument: (:) [Test-ExchangeServerHealth.
ps1], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Test-ExchangeServerHealth
.ps1
but if i open the powershell itself, navigate to the path and run the command it works great. hmmmm
Hi Paul,
First things first, just wanted to let you know this is a great little script.
I am having a small issue, I cannot seem to run the script using the Task Scheduler. It appears to run fine (no errors) but the html report doesn’t generate and I don’t receive an email.
When I run it from the command line, it works great every time. The report gets generated and I receive a nice email.
I’ve followed your instructions, plus I’ve adjusted the arguments and called the full path of the powershell command itself, but still no go.
Have you heard of anybody else having this trouble, or am I the lucky one? Windows Server 2008R2 Enterprise, with Exchange 2010 SP3.
Any tips or insight would be much appreciated! Thanks
Hi Jeff, I have it working in my environment via Task Scheduler. If you want to compare task settings maybe I can help.
For the record my settings are;
General tab: run logged in or not, with highest privileges. Configure for 2008R2.
Triggers tab: irrelevant, whatever schedule you want.
Actions: Start a program: powershell.exe
the command I have appended to it is;
-command “. ‘C:Program FilesMicrosoftExchange ServerV14binRemoteExchange.ps1’; Connect-ExchangeServer -auto; c:PsscriptsGet-MailboxReport.ps1 -all”
The remaining tabs, conditions, settings & history shouldn’t impact on it, but I also have the option to allow it to be ran on demand.
if you want a screengrab, please let me know. obviously i’ve made the changes in the script where needed for mail server etc etc.
Cheers, Shane.
ahh sorry, wrong script. here’s the command i’m using.
Actions – start a program – powershell.exe
-command “. ‘C:Program FilesMicrosoftExchange ServerV14binRemoteExchange.ps1’; Connect-ExchangeServer -auto; c:PsscriptsGet-DAGHealth.ps1 -detailed -sendemail”
The Real Person!
The Real Person!
The latest version doesn’t need all that in the command. The settings I use are in the blog post above the bug list/FAQ bit at the end.
Jeff, I’d suggest testing your Task Scheduler command in a cmd.exe window. See if that shows any errors (which will be a clue) or if it works fine (which will indicate that something in Task Scheduler is not right).
Giving it a try. Will let you know. Thanks for the post.
HI Paul,
We have 5 edge servers that I need to include for testing. I note in the script you say
“If you want to include then, remove this If.”
Being nowhere close to your skill level could you qualify the line numbers to remove? 409-423?
Finally it would be great if there was a disk space check in there but that a nice to have only
Thanks
Tony
The Real Person!
The Real Person!
Thanks for the suggestions. Since Edge is apparently here to stay in 2013 I have it on my list to add in some checks for that role.
I agree, disk space would be handy as well. Its on the list.
HI Paul,
One more thing- Public Folder databases and replicas check? Might be a tough one. I know you test the services but is anything more possible?
The Real Person!
The Real Person!
What specifically about public folder replicas?
Keep in mind that the way Exchange 2013 implements public folders means that is all changing anyway.
Specifically I’d like to test that the pf dbs are healthy and the replication is working.
Pingback: The UC Architects » Episode 22: A Game of Clouds
Have you considered adding transaction log stats?
Something line http://www.exchangebytes.com/?p=301
The Real Person!
The Real Person!
Yes, disk space is something I am working on including in future.
Any update on the disk space piece on mentioned you were working on?
Paul, I can’t seem to get this working in Exchange 2007, I have modified it to use the correct 2007 powershell plugin, and setup smtp settings correctly. However, when I run the script it gets past checking server roles, then closes the powershell window (crashes) with no errors that I see.
I am also facing the same problem in Exchange 2007 environment. Looking at previous comment from the people regarding Exchange 2007, it seems the older version of the script works fine for Exchange 2007.
Paul, Can we have the older version of this script? 🙂
Figured I would reply so others could fix it in 2007. I got it working using the following old script on 2007, just change the 2010 plugin to the 2007 plugin, comment out the 2010 Get-AD stuff, and add-in your smtp settings and you’re done.
http://dl.dropboxusercontent.com/u/13009245/facility.net/Test-ExchangeServerHealth.ps1
Also if anyone wants to setup scheduled task for this I got it working as well by created a batch file with the following code:
powershell.exe -command “. C:ScriptsExchangeServerHealthTest-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true”
Thanks Wooten. That worked for me 🙂 . Just want to check if this test runs HT Services and Transport queue for Edge Server as well. Or As Edge server is in DMZ, Do we need to open some ports to make this work?
Paul,
regarding “Healthy Queues” in the script, i can’t not really figure out, what that should mean. (and I also get a warning with a “2” in the field)
Can you explain the test in a few words?
Thanks
The Real Person!
The Real Person!
Each database copy has a copy/replay queue for replication. An unhealth queue is one that has more logs in the copy/replay queues than the $replqueuewarning is set to (which I set to 8, but you can adjust it higher if you want to).
Healthy Queues will be yellow (warning) if the number of healthy queues is less than the total number of queues.
In other words, if you’ve got 3 copies of a database, and all three copies have healthy queues, then “Health Queues” will be green. If only two of the copies have health queues, then “Healthy Queues” will be yellow.
Hi Paul,
I am using your script on a fresh Exchange 2010 Server and cannot get the serverroles-checks to work.
I always get something like “invalid argument, because it is NULL”, when binding parameter $serverinfoservices to -Name. Sorry that I can’t be more specific since I have the german version and have to translate this back to english
The Real Person!
The Real Person!
The script still has some issues with non-English languages that I haven’t gotten around to fixing.
Go to line 495 in the script and adjust the server role names there to your language and see if that fixes it.
Hi Philipp,
I already mentioned the changes, you must make to make this script running in german environments:
To all who want to use this script with different language-Exchange-Servers:
Regarding the errors on Exchange-Server in other languages:
You have to change the lines 346-349, where there are only the english server-role-names.
In the output with the error-messages, you can see the name of the roles in your own language, e.g in german:
“Hub-Transport-Serverrolle Services: Pass
Add-Member : Das Argument kann nicht an den Parameter “Name” gebunden werden, da es NULL ist….”
So you must change (or add lines) e.g. on german exchange-server:
“Clientzugriff-Serverrolle” { $roleservices = “CA Services” }
“Hub-Transport-Serverrolle” { $roleservices = “HT Services” }
“Mailbox-Serverrolle” { $roleservices = “MB Services” }
“Unified-Messaging-Serverrolle” { $roleservices = “UM Services” }
instead of(or additional to):
“Client Access Server Role” { $roleservices = “CA Services” }
“Hub Transport Server Role” { $roleservices = “HT Services” }
“Mailbox Server Role” { $roleservices = “MB Services” }
“Unified Messaging Server Role” { $roleservices = “UM Services” }
Additionally you must change the following line:
if ($testmailflowresult -eq “Success”)
to your own language, e.g. on german Exchange Server:
if ($testmailflowresult -eq “Erfolgreich”).
You can find the correct word of your language also in the output before you have fixed it:
Public Folder databases mounted: Pass
Mailbox databases mounted: Pass
MAPI connectivity: Pass
Mail flow test: Erfolgreich
After these changes the script works fine for my german exchange organisation
Update because of newer Version of Script:
I have added/changed the following line on a german Exchange Server:
Line 446:
I added 4 lines:
“Clientzugriff-Serverrolle” { $serverinfoservices = “Client Access Server Role Services” }
“Hub-Transport-Serverrolle” { $serverinfoservices = “Hub Transport Server Role Services” }
“Mailbox-Serverrolle” { $serverinfoservices = “Mailbox Server Role Services” }
“Unified-Messaging-Serverrolle” { $serverinfoservices = “Unified Messaging Server Role Services” }
After that I changes line 604 to:
if (($mapiresult -ne “Success”) -and ($mapiresult -ne “Erfolgreich”))
and I changed line 651 to:
if (($testmailflowresult -eq “Success”) -or ($testmailflowresult -eq “Erfolgreich”))
I don’t have DAG in my environments, could anyone, who has DAG and german (or other not-english exchange-server) please test, what happens with the DAG-Check?
is there any script for performance metrics for exchange server
-jeevan
Paul,
Thanks for the updated server health check script! We greatly appreciate the freebies you provide to help us monitor Exchange. 🙂
I’ve tried to modify the script so that emails are only sent when there is an error or warning detected. In the process I noticed two variables called $alerts and $AlertsOnly. I tried to use the AlertsOnly as a switch as listed in line 139 but was unable to get it to work. I read through the comments section as well and noticed you mentioned adding the feature of only emailing if an issue was found. Suggestions?
Thanks!! 🙂
The Real Person!
The Real Person!
Looks like some code slipped in for the “Alerts Only” option that I haven’t finished fully implementing and testing yet. I have it on my list of improvements I’m working on.
Thanks Paul for your update
Hi Paul,
Love your script. I used the previous version like a charm! Had it set on a schedule task and only e-mail if there was a failure.
In the new version, not sure where to put the ‘Exit’ command so it doesn’t send an e-mail if there are no Server or DAG Health issues.
Second, if there is a DAG issue, it doesn’t say that in the email. Says the following:
Exchange Server Health Check Summary
No Exchange server health alerts or warnings
Exchange Server 2010/2007 Health
Maybe add something after the “No Exchange Server Health Alerts or Warning” if there are any DAG issues so we can scroll down to take a look.
Thanks again!
The Real Person!
The Real Person!
Correct, that summary only refers to server health at the moment, not DAG health. I will be adding more summary details in the next version.
But generally speaking I recommend people at least skim through the entire report looking for yellow/green rather than just rely on the summary 🙂
Hi Paul,
I trying to run the script for send report to me. But it’s couldn’t send mail to me. I ran the scripts on the Hub Server and i change the smtp settings already. This is the results after ran the scripts is show below.
—- Server Test-Replication Report —-
Server ClusterServ ReplayServi ActiveManag TasksRpcLis TcpListener DagMembersU ClusterNetw QuorumGroup FileShareQu
ice ce er tener p ork orum
—— ———– ———– ———– ———– ———– ———– ———– ———– ———–
MBXPN01 Passed Passed Passed Passed Passed Passed Passed Passed Passed
MBXPR01
MBXPR02 Passed Passed Passed Passed Passed Passed Passed Passed Passed
—— Finishing
Done.
[PS] D:ScriptTest-ExchangeServerHealth>
Thanks
and have this error :
Windows Failover Clustering encountered a transient error. Trying the operation again may be successful. Error: ‘IsNod
Clustered’.
+ CategoryInfo : NotSpecified: (0:Int32) [Test-ReplicationHealth], ExClusTransientException
+ FullyQualifiedErrorId : 33AD0105,Microsoft.Exchange.Monitoring.TestReplicationHealth
Add-Member : Cannot bind argument to parameter ‘Name’ because it is null.
At D:ScriptTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1:880 char:47
+ $memberObj | Add-Member NoteProperty -Name <<<< $($healthitem.Check) -Value $($healthitem.Result)
+ CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCo
mmand
Thanks a lot
The Real Person!
The Real Person!
What is the full command you’re using to run the script?
[PS] D:ScriptTest-ExchangeServerHealth>.Test-ExchangeServerHealth.ps1
This is command i ran it.
Thank for your quickly answer
The Real Person!
The Real Person!
Can you please review the instructions in the article again. They explain how to run the script to get an email report sent to you.
i set the schedule task that you recommend Arguments: -command “C:ScriptsExchangeServerHealthTest-ExchangeServerHealth.ps1 -reportmode -sendemail” and then i click run this schedule task but i don’t received the mail report to me. Not sure why its don’t send mail to me. and i confirm that i change the smtp settings already.
The Real Person!
The Real Person!
Try running it in your Exchange Management Shell:
.Test-ExchangeServerHealth.ps1 -reportmode -sendemail
That way you’ll see any errors that occur when the email is attempting to send.
It is also worth double checking the email settings you’ve configured. Often people make a typo or miss a closing quote and it fails as a result. You should also make sure the server you’re running the script from is in the list of allowed IP addresses for the relay connector you’re pointing it at.
Thanks you very much Paul 😀
Thanks Paul. Grate script as usual.
I remember in your previous script you had a column for backup as well, I don’t see in this script.
Question: I am new to this Exchange 2010 and still struggling with many things.
After I run this script I found error in Cluster Network (Failed). When I checked in DAGNetwork01 configuration it shows [subnets] 10.32.100.0/24 is Misconfigured, whereas DAGNetwork02 [Subnets] shows fe80::/64 Unknown.
Any suggests how to fix it.
Thanks
The Real Person!
The Real Person!
You possibly need to review and collapse your DAG networks. The best resource for this is Tim McMichael’s blog post here:
http://blogs.technet.com/b/timmcmic/archive/2011/09/26/exchange-2010-collapsing-dag-networks.aspx
G’day Paul,
Stellar work on this version of the health script. Works a treat with just a couple of tweaks to the batch file we use to run it.
Would it be possible to stretch the friendship and ask if it’s possible to include storage usage, eg, available/used/overall per HDD or per LUN/array?
Kerry
The Real Person!
The Real Person!
I have been experimenting with that and the biggest challenge is accounting for all the different mixes of dedicated log/DB LUNs vs shared log and shared DB LUNs vs multiple databases on a single LUN and so on and so on, while still presenting the results in a useful way.
Of course I love a challenge, so I will probably get it done some day, just not any time soon to be honest 🙂
Works perfectly, thanks Paul. awesome stuff that’s truly appreciated 🙂
Cheers Shane.
The Real Person!
The Real Person!
The script has been updated to v1.2, available at the same download link. This version includes several bug fixes and also adds the DAG health check.
Please review the notes and instructions as some things have changed, eg the SMTP settings that you customize.
Thanks everyone for your feedback and bug reports so far.
Paul,
i’m still struggling to bring “test-owaconnectivity” and “test-activesyncconnectivity” to your script. Everything else is working flawless, but i got everytime a bunch of error messages by implement other cmdlets besides the existing ones.
You have a hint to do that?
Thanks, Flo
The Real Person!
The Real Person!
I happen to be working on a script to run those CAS test cmdlets, and yes, they are a bit tricky to work into a script.
Yes, I’m trying to get them into the main script for two days now. Really tricky. I will continue to work on that, but maybe you are faster. 🙂
To all who want to use this script with different language-Exchange-Servers:
Regarding the errors on Exchange-Server in other languages:
You have to change the lines 346-349, where there are only the english server-role-names.
In the output with the error-messages, you can see the name of the roles in your own language, e.g in german:
“Hub-Transport-Serverrolle Services: Pass
Add-Member : Das Argument kann nicht an den Parameter “Name” gebunden werden, da es NULL ist….”
So you must change (or add lines) e.g. on german exchange-server:
“Clientzugriff-Serverrolle” { $roleservices = “CA Services” }
“Hub-Transport-Serverrolle” { $roleservices = “HT Services” }
“Mailbox-Serverrolle” { $roleservices = “MB Services” }
“Unified-Messaging-Serverrolle” { $roleservices = “UM Services” }
instead of(or additional to):
“Client Access Server Role” { $roleservices = “CA Services” }
“Hub Transport Server Role” { $roleservices = “HT Services” }
“Mailbox Server Role” { $roleservices = “MB Services” }
“Unified Messaging Server Role” { $roleservices = “UM Services” }
Additionally you must change the following line:
if ($testmailflowresult -eq “Success”)
to your own language, e.g. on german Exchange Server:
if ($testmailflowresult -eq “Erfolgreich”).
You can find the correct word of your language also in the output before you have fixed it:
Public Folder databases mounted: Pass
Mailbox databases mounted: Pass
MAPI connectivity: Pass
Mail flow test: Erfolgreich
After these changes the script works fine for my german exchange organisation
Paul,
Great stuff this script , we use it 24/7.
Any word on when the new 1.2 version will be ready for download?
Can’t wait!
Hi Paul,
Thanks for your script.
I have a small issue. Please help me.
I am supporting different clients with 2010 and 2007 exchange. I have implemented this script via task for exchange 2010 and working fine.
But recently i did this for one of my 2007Box and i am getting the full result only if i manually run the script in exchange / windows powershell.
if i run it via task i amnot getting the full details. after the summary the exchange health check details not showing. Please see the below sample report
Exchange Server Health Check Report
Generated: 04/02/2013 21:28:05
Exchange Server Health Check Summary
No Exchange server health alerts or warnings.
Note: If i run the script directly from shell, i am getting all the results.
Please help me..
Thank You
Sreejith
The Real Person!
The Real Person!
The script is written to work with Exchange 2010. I suspect what you will need to do is replace the section early in the script that calls the Exchange 2010 snapin with the name of the Exchange 2007 snapin instead.
Thanks Paul.
I will try that.
But i got fixed this by running a batch file. the content of the btch file is
Cd “D:Program FilesMicrosoftExchange ServerBin”
C:WindowsSystem32WindowsPowerShellv1.0powershell.exe -psconsolefile “D:Program FilesMicrosoftExchange ServerBinexshell.psc1” -command “”
Thank You
Sreejith
Paul,
How can i get the script to report the queue length as a number, instead of Pass/Fail in the email report?
The Real Person!
The Real Person!
My current version lists the queue count next to the pass/fail result. Not sure if that is in the publicly released on yet though, but it will be in the next version I release.
Paul,
Love the script, have used it for 6 months or so and it really helps me have a quick look to identify any issues that I would normally have to log into each server and run checks manually.
My only issue is that recently we have moved a couple of servers out of a DAG, but they are still in service because they have public folders that are in use, until we can move and decom. During the test, those servers warn (which I expect) during the mail flow test that “No mailbox databases”.
However, once the checks continue on to other servers that DO have mailbox databases available, I continue to get the warning message. I’m not a programmer by any stretch, but is it possible that the result for that test doesn’t get re-initialized?
Thanks for all you do in helping us admins survive!
The Real Person!
The Real Person!
That is possible. In the version I’m working on right now I can’t see a bug that would cause that, so its possible I’ve already fixed that up. That version will be out soon I hope.
Thanks!
Paul,
Just downloaded the new version, and ran it. It definitely fixed the issue with databases showing as not available. Thanks!
When I run script via Exchange powershell all roles services indicate as PASS with green color
but
When I run script via Task Scheduler all roles services indicate as Fail with red color.
please help me on this.
The Real Person!
The Real Person!
Is your scheduled task configured to run with highest privileges?
yes it is configured to run as domain Administrator
The Real Person!
The Real Person!
I mean the scheduled task itself, there’s a tick box to run with highest privileges.
Thanks Very much paul,…… you are amazing…
Running with highest privileges….. resolves the issue….
Thanks for wonderful script…..
Paul,
I have used the scripted and you did a very good job.
However I do not want to run this script from any of the Exchange servers, because if this particular server fails, I will not get any report. So I thought it would be good idea to install it on separate server.
What do I need to install on a separate Win 2008 R2 server to run the script with success? Do I need to install the Exchange System Management Tools or is it enough to have a PowerShell with some additional add-ins?
Mike
You can certainly install the management console but you can do it remotely as well. Check out the manual section in this link to set up a “new-pssession“.
http://www.mikepfeiffer.net/2010/02/managing-exchange-2010-with-remote-powershell/
Thx Stephen – nice article.
I have tried that.
I have open the Power Shell on the Win 2008 R2 computer, and run the following command to connect to the Exchange remotely:
$s = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri
http://[exchange FQDN]/PowerShell/
-Authentication KerberosImport-PSSession $s
And I cannot get through one thing – I cannot get this command to work on the remote server which doesn’t have Exchange manangement tools installed.
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
This command is one of the first in the scipt written by Paul.
Do you have any idea how to overcome it?
Another Great script!
I have about 50 servers in my environment. Is there a way to have the script run the report by alphabetical server name? I have the servers hard-coded into the script alphabetically but it doesn’t seem to work.
The Real Person!
The Real Person!
Look for this line:
$tmpservers = @(Get-ExchangeServer | sort site,name)
You can change that to sort by just name if you like.
Hey Paul,
I am using PS 3.0 and the send mail feature has changed it should be send-mailmessage.
I can’t figure out what all to change in your script for me to get an email sent
any help would greatly be appreciated
Thanks Bill
Hey Paul,
I fixed the email problem. I did notice another issue…The report is not giving me any mail flow results???
Any help would be appreciated
Bill
The Real Person!
The Real Person!
I haven’t tested any of this script with PS 3.0 so its possible you will see problems.
Paul
Is there an updated version of the script yet? I have a July 2012 version still.
Kind Regards
Cathryn
The Real Person!
The Real Person!
The latest version (same download link above) is from August 2012 and fixes a few bugs in that earlier version.
A new version will be coming in the next few weeks I hope.
Hi Paul,
Is it possible to run this script with SCOM 2012 server.?
Helllo, thank you, but need some help.
I getting this error
Mailbox databases mounted: Pass
Mail flow test: No active mailbox databases
—— Checking RU-EXCH1
DNS Check: Pass
Server up: Pass
Uptime (hrs): 352
Server version: Exchange 2010
Roles: Mailbox
Роль сервера почтовых ящиков Services: Pass
Add-Member : argument parametr”Name”, value NULL.
C:scriptsExchangeServerHealthTest-ExchangeServerHealth.ps1:358 знак:52
+ $serverObj | Add-Member NoteProperty -Name <<<< $roleservices -Value $svchealth
-Force
+ CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCo
mmand
Mailbox databases mounted: Pass
MAPI connectivity: Pass
The Real Person!
The Real Person!
This is probably a problem due to non-English language and it is something I am trying to fix in the next version.
ok thanks, that will be very helpful
i am using russian version of Exchange 2010 and R2, maybe i need to resave ps1 in utf8 format or set encoding string somewhre?
Regarding the errors on Exchange-Server in other languages:
You have to change the lines 346-349, where there are only the english server-role-names.
In the output with the error-messages, you can see the name of the roles in your own language, e.g in german:
“Hub-Transport-Serverrolle Services: Pass
Add-Member : Das Argument kann nicht an den Parameter “Name” gebunden werden, da es NULL ist….”
So you must change (or add lines) e.g. on german exchange-server:
“Clientzugriff-Serverrolle” { $roleservices = “CA Services” }
“Hub-Transport-Serverrolle” { $roleservices = “HT Services” }
“Mailbox-Serverrolle” { $roleservices = “MB Services” }
“Unified-Messaging-Serverrolle” { $roleservices = “UM Services” }
instead of(or additional to):
“Client Access Server Role” { $roleservices = “CA Services” }
“Hub Transport Server Role” { $roleservices = “HT Services” }
“Mailbox Server Role” { $roleservices = “MB Services” }
“Unified Messaging Server Role” { $roleservices = “UM Services” }
Additionally you must change the following line:
if ($testmailflowresult -eq “Success”)
to your own language, e.g. on german Exchange Server:
if ($testmailflowresult -eq “Erfolgreich”).
You can find the correct word of your language also in the output before you have fixed it:
Public Folder databases mounted: Pass
Mailbox databases mounted: Pass
MAPI connectivity: Pass
Mail flow test: Erfolgreich
After these changes the script works fine for my german exchange organisation
Pingback: Get-DAGHealth.ps1 - Database Availability Group Health Check Script
Thank you so much for sharing this magnificent piece of work.
You have obviously put a lot of effort into this, not just the script but also the commentary and how-to guides
Thank you again
P.S> I’m a big fan of your articles and have used many of them in the past. Keep up the good work !!!
I tried this command with scheduled task. but it’s not happening. Please help me.
Sorry… It’s already there…
Thanks for this script.
Need one help. how can i include DB mount status to this report ?
Hi Paul,
Great script!! Need some help in adding this script to Task Scheduler for a daily email report. I have added the option -reportmode $true -sendemail $true in the “Add Argument” section in Task Scheduler and powershell.exe “program/script” but it doesn’t work!!
Kindly assist me!!
Regards
Akash
I ended up tweaking the email section in the script so it would just go out my Outlook application.
if ($sendemail)
{
$ol = New-Object -comObject Outlook.Application
$mail = $ol.CreateItem(0)
$Mail.Recipients.Add($smtpto)
$Mail.Subject = $messageSubject
$Mail.HTMLBody = $htmlreport
$Mail.Send()
}
Very much waiting for the DAG health section.
One additional question that I think has been asked already in the comment but I will ask again. We have two MX servers and one of them does not have any datastores active on it and I get the following warning on the passive DAG server.
Mail flow test: WARNING: Exchange can’t perform the mail flow test because currently there are no mailbox databases on server *SEVERNAMETAKENOUT*.
The Real Person!
The Real Person!
That warning is normal under those conditions. I think the new version I’m working on accounts for that scenario a bit better.
I have Exchange 2013 installed on my lab and i try your script its showing me this error
[PS] E:script>.Test-ExchangeServerHealth.ps1 -server ex
Initializing…
—— Checking EX
DNS Check: Pass
Server up: Exception calling “Send” with “1” argument(s): “An exception occurred during a Ping request.”
At E:scriptTest-ExchangeServerHealth.ps1:248 char:4
+ $result = $ping.send($ip)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : PingException
You cannot call a method on a null-valued expression.
At E:scriptTest-ExchangeServerHealth.ps1:249 char:8
+ if ($result.status.ToString() -eq “Success”)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
when I run the script “Test-ExchangeServerHealth.ps1” it appear the message
“Call was canceled by the message filter. (Exception from HRESULT: 0x80010002 (RPC_E_CALL_CANCELED))”
I want to check time to replicate from DC site to DR site (Server name: DR-mailbox-03 to HQ-mailbox-03), I also to know time to connected two server.
Hi,
Is it possible to only get an e-mail if there is a failure? What I want to do is setup a task to run every 10 minutes or so, and only send an e-mail if something fails.
Nevermind, I see a similar post and solution here.
The script file has been saved to the C:temp folder on our Exchange server.
The following command is run in EMS version 2.0 on the Exchange server.
[PS] C:temp>Test-ExchangeServerHealth.PS1 -server EXG
Result as follows:
[PS] C:temp>Test-ExchangeServerHealth.PS1 -server EXG
The term ‘Test-ExchangeServerHealth.PS1’ is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:30
+ Test-ExchangeServerHealth.PS1 <<<
Can anyone tell me why this is not working?
Helps if I actually extract the script files. Now I get this.
[PS] C:temp>.Test-ExchangeServerHealth.PS1 -server HADEG
File C:tempTest-ExchangeServerHealth.ps1 cannot be loaded. The file C:tempTest-ExchangeServerHealth.ps1 is not digi
tally signed. The script will not execute on the system. Please see “get-help about_signing” for more details..
At line:1 char:32
+ .Test-ExchangeServerHealth.PS1 <<<
I see. OK that’s it for today. I’ll try this next week.
TO PERMIT SIGNED SCRIPTS TO RUN
——————————-
When you start Windows PowerShell on a computer for the first time, the
Restricted execution policy (the default) is likely to be in effect.
The Restricted policy does not permit any scripts to run.
To find the effective execution policy on your computer, type:
get-executionpolicy
To run unsigned scripts that you write on your local computer and signed
scripts from other users, use the following command to change the execution
policy on the computer to RemoteSigned:
set-executionpolicy remotesigned
For more information, see Set-ExecutionPolicy.
RUNNING UNSIGNED SCRIPTS (REMOTESIGNED EXECUTION POLICY)
— More —
I am getting the same error. Any idea what resolved this for you?
The Real Person!
The Real Person!
The script isn’t signed. You’ll need to adjust your PowerShell execution policy to run it.
This script has been a great help but we have noticed an oddity. We run the script in a scheduled task. The task calls a batch file with in turns calls the power shell script. Here is the oddity. when called by the scheduled task one of our exchange servers reports three failures, CA HT, and MB services. When I run the batch file myself, double clicking the batch file, the report shows no failures. The batch file is called using the same credentials. The only difference is a scheduled task is calling the batch file and not by a user clicking the the batch file.
get-reports.bat
Scheduled task reports failures.
User double click reports no failures.
any thought on this?
Thanks,
Paul
Hi Paul,
This very great work you did. It helped a lot for us.
But this script failed to send the CA,HT services while running from scheduler.
It is running fine from shell prompt, and it is not updating the .html file generated at c:scripts while run from scheduler.
Thanks.
Thanks for this script.
I have one issue that I hope you can answer.
I have pointed the smtp to my smtp server but I still get the:
Exception calling “Send” with “1” argument(s): “Failure sending mail.”
At C:nttaSoftwareTest-ExchangeServerHealth1Test-ExchangeServerHealth.ps1:809 char:13
+ $smtp.Send <<<< ($message)
Error.
My SMTP server is configured to accept on port 587.
Is the script attempting to send on port 25? How do we change this?
Pingback: I recommend this Exchange health check script!!! « GAPTHEGURU
Hi Paul,
I’m new to this, it works perfectly if I run it in EMS on 2007 but I cannot figure out how to call it from a batch file? Please can you assist?
Thanks
Exception calling “Send” with “1” argument(s): “Failure sending mail.”
At C:ScriptTest-ExchangeServerHealth.ps1:808 char:13
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Hi Paul,
Great script. Thanks for sharing!
Hi Paul,
thanks for all your hard work! in you new version can it be set up to email a second address only if there is a critical issue?
Any way you can change your parameters in the next release a little? I rewrote it a bit to be more flexible partially for selfish needs but still could be useful for others.
Parameters section:
param (
[Parameter( Mandatory=$false)]
[string]$server,
[Parameter( Mandatory=$false)]
[bool]$reportmode=$false,
[Parameter( Mandatory=$false)]
[string]$reportfile=”exchangeserverhealth.html”,
[Parameter( Mandatory=$false)]
[bool]$sendemail=$false,
[Parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[Alias(‘SMTP Server’)]
[String]$smtpServer = “localhost”,
[Parameter(Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)]
[Alias(‘Email Sender’)]
[String]$smtpFrom = “healthcheck@localhost”,
[Parameter(Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)]
[Alias(‘Email Recipient’)]
[String]$smtpTo = “you@somplace.com”
)
The Real Person!
The Real Person!
Yeah. Actually all my scripts suffer from some inflexibility when it comes to paramaters and such, relying on editable variables in the script code. I’ve got a priority goal as I update them all for Exchange 2013 to make them more flexible in that sense.
Since everyone keeps asking for a dag database replication report I went ahead and created an initial version based on Paul’s code and another project’s code. Seems to work well enough for me. Let me know what you think. You can grab the script from here:
http://gallery.technet.microsoft.com/scriptcenter/Exchange-DAG-Replication-d8e99705
The Real Person!
The Real Person!
Haven’t tested yours but it looks neat.
I’ve nearly got my stuff ready. Its been a tough few months trying to find time to do the updates on this script 🙂
Hi Paul,
The script looks great but I’m not a programmer nor do I have a lot of experience with a command line. Does the script add/modify anything on the server or in AD or make any changes when run? I too am interested in a DAG check as well.
Thanks,
Tom
Pingback: Exchange 2010 health check script « Doug G
Hey Paul,
Great Script. I like it.
Please can you expand the exchange server version in your next script… For example: Exchange 2010 SP2, server build… blab blab…
thanks,
–Scot
Great script Paul.
But i get a strange issue. If I run a script on EMS with reportmode and sendmail parameters (.Test-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true) – results as expected.
Once I schedule a task to run script – all works thou results i get are not correct. I get CA,HT,MB service checks failing all the time on server i run task on.
Those services are up, I also get Pass results if I run scripts from EMS.
My Exchange setup is: 2x Exch Servers 2010 SP2 with Mailbox, ClientAccess, HubTransport Roles.
Looking forward for your comments. Thanks.
Tom
The Real Person!
The Real Person!
Hi Tom, are your servers configured for a language other than English?
Hi Paul,
Nope. Language is english.
Hi Paul,
Not sure what was the issue but script works OK now. Deleted scheduded tasks, re-done, copied over script again. Issue fixed.
Thanks.
Hi Paul,
I wanted to run this script in my environment, but I need to include credential to send out email using the SMTP.. Is there anyway to use my credential with the script ?
Thanks you for the great script! I wanted to add the information that was output after the fail. In my case it looks like this.
Public Folder databases mounted: Pass
Mailbox databases mounted: Fail
Offline databases:
Mailbox Database DB6
I’d like to include this in the report.
Server Errors Warnings
EXG-SVR2 Mailbox databases not mounted. MAPI tests failed. (currently blank) Mailbox Database DB6
It would be nice to see what was causing the error in the email.
How or where can i implement this in the script. I am new to power shell but I do have programming experience.
Thanks again for this great script!
Paul
The Real Person!
The Real Person!
A very early version of the script actually did do that but I took it out because (a) the code itself was pretty messy, and (b) it made a terrible mess of the HTML report/email when a server had a bunch of different things wrong with it (eg if the Information Store is down, you get that plus all the DB’s offline plus all the failed MAPI tests so it becomes a big mess in the report).
Thanks for the note and quick response.
Paul
Thanks Paul, excellent script, my only problem is that I have not yet received the HTML report via email 🙂
I have set the smtp info as per above for our environment
never mind its running 100%, mail flow was a bit slow thru our smart host
Nice script, looking forward to the DAG checks.
First, I wanted to say what a great report this is, very helpful tool.
Second, the reason I found this was my search for copy status health checks. Were you able to make any progress on adding that back in?
Thanks for the great tool
James Mc
Thank you very much for great script.
My little troubleshooting about this error, that some got:
Cannot convert value “1 301” to type “System.Int32”. Error: “Input string was not in a correct format.”
You using this statement to format total hours: [int]$uptime = “{0:N0}” -f $uptime
So because of Russian locale on my servers I have ” ” (space) as Digit grouping symbol.
That’s why we got “1 301” in result that cose error to convert into integer value.
So I just replace one simbol (N to D): [int]$uptime = “{0:D0}” -f $uptime
And now have no error with this.
Hope this help.
PS. In fact I found days in this parameter more helpful, so I change to this:
[int]$uptime = (New-TimeSpan $laststart $now).TotalDays
[int]$uptime = “{0:D0}” -f $uptime
and
“Uptime (hrs)” to “Uptime (days)”
Thank you again.
Waiting for new version of script!
Best regards,
Oleg A.
The Real Person!
The Real Person!
Thanks for that feedback. Very useful.
i wanted to use for exchange 2007 in production environment so can you pls help me how can i alter the same and use with exchange 2007.
What i observed that when i am running the script i am getting the below error but seems to be it is going through. So what change I can do if wann use with exchange 2007 or can I ignore get-ADserver Settings error as I know this is because of exchange 2010, so if I can ignore the error or change something in script to use with exchange 2007. PLs help.. Thanks
[PS] C:\>.Test-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true
Initializing…
The term ‘Get-ADServerSettings’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a
path was included, verify that the path is correct and try again.
At C:Test-ExchangeServerHealth.ps1:83 char:27
+ if (!(Get-ADServerSettings <<<< ).ViewEntireForest)
+ CategoryInfo : ObjectNotFound: (Get-ADServerSettings:String) []
, CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
—— Checking CASHUB
DNS Check: Pass
Server up: Pass
Uptime (hrs): 0
Server version: Exchange 2007
Roles: ClientAccess, HubTransport
Client Access Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 1
—— Checking MBX
DNS Check: Pass
Server up: Pass
Uptime (hrs): 0
Server version: Exchange 2007
Roles: Mailbox
Mailbox Server Role Services: Pass
Mailbox databases mounted: Pass
Mail flow test: Success
—
The Real Person!
The Real Person!
Get-ADServerSettings is an Exchange 2010 cmdlet.
If you’ve got Exchange 2007 and only a single domain in the forest then just commend that part of the script out.
Hi Paul,
love this script, used at a couple of individual sites and works like a charm! are you planning on implementing DAG and Database Copy status into the script?
Regards
Sam
The Real Person!
The Real Person!
Yes, DAG health is on the to do list.
Hi Paul,
This script is great and i’ve been using it for a while. However I’m getting a false failure on one server for HT services. Tranport and mailflow both are fine. If I check services, all are fine and the server is fully working. Any idea what would cause the false positive?
thanks
Paul
The Real Person!
The Real Person!
On the server in question run Test-ServiceHealth and it will tell you which service is not running.
Hi,
Paul, its a great script..I have run it in my organization with a success. I want to patch to more options in this script i.e. Disk space alerts and backup alerts.
how i can go about that.
Thanks
Hemant M.
The Real Person!
The Real Person!
There’s a backup alert script that I wrote here:
https://www.practical365.com/set-automated-exchange-2010-database-backup-alert-email
I’ll look at disk space alerts in a future version.
Not quite the same but I did wrap a script around Paul’s handiwork which includes a disk space report and other functionality (http://gallery.technet.microsoft.com/scriptcenter/Troubleshoot-Exchange-2010-aecdc23f)
Hi Paul I am running this command as explained in the video .test-exchangeserverhealth.ps1 -reportmode $true -sendemail $true
and throws me the following error
File C:UsersarouradesktopTest-ExchangeServerHealth.ps1 cannot be loaded. The file C:UsersarouradesktopTest-Ex
angeServerHealth.ps1 is not digitally signed. The script will not execute on the system. Please see “get-help about_s
ning” for more details..
At line:1 char:32
+ .Test-ExchangeServerHealth.ps1 <<<<
+ CategoryInfo : NotSpecified: (:) [], PSSecurityException
+ FullyQualifiedErrorId : RuntimeException
that could be?? says something of a digital signature
thanks for your help.
regards
Antonio Roura.
Paul, thank you for script.
I think it is better to include information about CPU loading and free space at hard drives.
I second this request as this is a major concern… Hard Disk getting full and not aware of this can and has created havoc many times…
Is there a way to add HDD consumption/ free/ space data into these reports.
Thanks for such awesome efforts & script… gives insight and foresight of exchange environment
Thanks,
Pingback: Exchange 2010 Health Check, is my Exchange Server OK? | The Daily Byte
Good morning Paul,
I was wondering if it would be possible to add to your AWESOME script, a health check of all the “Content Index Catalog”?
Much appreciated sir 🙂
The Real Person!
The Real Person!
Planning to include CI health in an upcoming version.
sooo excited for the updated version! 😉
Pingback: Exchange Server 2010 – Failover & Maintenance | f i c i l i t y .net
Pingback: Exchange Server 2010 – Maintenance | f i c i l i t y .net
Excellent script, thanks very much.
One small change I made was to edit line 356 from:
$false {$svchealth = “Fail”; Write-Host -ForegroundColor $fail “Fail”; $serverObj | Add-Member NoteProperty -Name “Error Details” -Value ($($serverObj.”Error Details”) + $string5) -Force }
to:
$false {$svchealth = “Fail”; Write-Host -ForegroundColor $fail “Fail”; $serverObj | Add-Member NoteProperty -Name “Error Details” -Value ($($serverObj.”Error Details”) + $string5 + $s.ServicesNotRunning) -Force }
Adds the detail from Test-ServiceHealth failure to the Error Details table.
Hey Paul,
Thanks again for being a rock star. I integrated your script into my own as best as I could. If you see any areas of improvement or don’t like my describing your health report as “kick-ass” please let me know and I’ll do my best to fix things up.
http://gallery.technet.microsoft.com/scriptcenter/Troubleshoot-Exchange-2010-aecdc23f
The only item I was tempted to change was adding an option to spit out the html report as a returned value and adding a silent mode so I could more easily wrap code around it.. That is not really a feature request though as I’m guessing only a small majority of people using your script are needing that kind of thing (only weirdo fellow scripters like myself).
Regards,
Zach
Hello Paul,
I’m not certain how I missed this particular release of yours until today. Good job on the health test script! I’ve recently released something a bit like this but just for using the built in scripts that come with exchange 2010 (http://gallery.technet.microsoft.com/scriptcenter/Troubleshoot-Exchange-2010-aecdc23f). If I rolled in your script as an optional parameter (would set it up to call your script which others would need to manually download from your site to utilize probably) would you mind? Or maybe even the other way around?
Cheers and thanks again for sharing with the community!
The Real Person!
The Real Person!
Hi Zach, feel free to incorporate any of my scripts into your own however you wish, whether as an external dependency or by reusing code. If its something you’re publicly releasing a credit in your script help/comments would be appreciated 🙂
Absolutely, I’d have it no other way good sir 😉 As you maintain your script I’ll just make it an external dependency. Updates forthcoming soon.
Hi Paul,
Great Script! Love it! One thing, is it possible to get the number of messages in the Queue in the e-mail report?
Great Script! Thanks Paul.
Thanks for the awesome script! I’m new to Powershell and 2010 but we just built out our 2010 servers with 4 Mail DB servers in a DAG. Any chance of incorporating something from Get-MailboxDatabaseCopyStatus into the script? I think you said that was coming in a future version, but just checking. It would be a helpful addition for us to know if we need to reseed or anything.
Hi Paul,
On the original script, content indexing is included. Is it possible to include it again? Thanks!
Hi Paul,
Thanks for your great work. I have 2 queries:
1. Can we exclude PF databases to be checked? Incase I have PFs remotely over a WAN link?
2. I am not able to restrict the script to run only on my current Site, it goes to different sites over WAN link and check every server which results in a lot of Red (which I hate to see :))..
thank you in advance for your reply.
Also, could you please suggest nice training material for Powershell for exchange?
Pingback: PowerShell Script to Generate a Health Check Report for Exchange Server 2010. « You've got mail!
Hi Paul,
thanks for that great script. I have an proposal for the health check: We use the Outlook Web Access and Active Sync. Is it possible to include those tests too? That would be great because otherwise i have to check those services with a different script.
Greets
Alex
The Real Person!
The Real Person!
Have added them to my notes as feature requests. We’ll see how it goes 🙂
Thanks Paul, great script!!
Would be great to have this be installed to run at defineable intervals (e.g. every 5 minutes), but only email if the HTML output has materially changed due to a significant change in status (i.e. a server that was down is now up).
Another idea would be to capture perf statistics (e.g. how many MAPI users are logged on, how many through OWA, etc.). This might be a whole other script or at least not activated by default.
Tx
–sc
The Real Person!
The Real Person!
When this script was originally created I had two goals:
1) Do a real time, quick health check of a server (eg someone says “Hey is email not working?” you can quickly run it and see whether any obvious issues are there.
2) A daily health check report that I can check via my iPhone early in the morning to see if any issues have arisen overnight, before business hours begin.
It never was, and probably never will be, intended to be used for continuous monitoring and alerting during the day. There are much better solutions for that, for example Andy has a series of articles on using Nagios for monitoring Exchange:
http://www.telnetport25.com/2012/01/installing-nagios-on-ubuntu-server-11-10-then-monitoring-windows-and-exchange-serverspart-1configuring-ubuntu-for-the-installation-of-nagios-core/
But, the script code is freely released to the public for anyone to use and adapt as they see fit. So you might take it on board as something you develop further, by all means do 🙂
The Real Person!
The Real Person!
I’ve just uploaded v1.1 which has just a few minor bug fixes in it. I’ve also added a bug list/FAQ section to the end of the article to let everyone know which issues I’m working on.
Thanks for all the work
Were do I download newest file (must be blind lol)
Thanks Again
The Real Person!
The Real Person!
Same download link as before, in the article. I update the file on the back end.
Wow Thanks for the speedy Reply Have a good day
So… I guess an obvious but silly question… I have it set up. And it is working AMAZING. But… if there is a disruption in mailflow for whatever reason… will it still be able to send the email message? LOL. I used the “EXIT” command to stop it if there is not a problem. So… if there is a problem, and it sends the email message, will it still be able to send it? If that makes sense…
The Real Person!
The Real Person!
Valid point. If there is a critical mail flow issue in your environment then of course the report email will also likely not be delivered.
But the HTML report file that is generated can be used instead in those cases. So if you direct that file to a specific location using the -reportfile parameter, and are running IIS, you can open the HTML report via your web browser (even have it as one of your home tabs for the start of the work day).
Paul,,, When it gets to mail flow test I just get the following – *FAILURE*
Any ideas?
The Real Person!
The Real Person!
Mail flow tests are failing 😉
Next version is going to use a simpler mail flow test (that is also slightly less thorough) to avoid some bugs that are cropping up.
Hi Paul,
Many thanks – your script is a life-saver!!
However, I am having similar issues with the Mail Flow Test.
We have an Exchange 2013 environment. I am running the script in a scheduled task with the argument below:
Powershell -executionpolicy bypass -file C:1ScriptTest-ExchangeServerHealthSW.ps1 -Log -SendEmail
The report that gets mailed always shows that “mail flow test failed” on both my exchange servers. If I directly run the same command in Powershell or via Start > Run, I get a Pass for all the tests.
I had a look at the Log generated, and the one line in there says “11/30/2015 13:45:03 The term ‘Test-Mailflow’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
11/30/2015 13:45:03 Mail flow status is Fail”
Please help when you can, I have no clue what’s going on.
Thank you,
Oh and I’m running the version of your script found here:
https://gallery.technet.microsoft.com/scriptcenter/Generate-Health-Report-for-19f5fe5f
The Real Person!
The Real Person!
Might be just the PS remote session failing. I’d need to see the full log. You can email it to me at paul (at) this domain.
Thanks Paul – I have now mailed you the log.
Granting the service account “Server Management” permissions solved my issue. Many many thanks Paul!! 🙂
Paul,
First of all, thank you for the script. I found an error condition that involves my Edge Transport Server. I run the script from my Exchange server that has the Mailbox, ClientAccess, and HubTransport roles. Next the script queries my EdgeTransport server. Since the EdgeTransport sits in my DMZ and is not actually in my domain, for it I get:
DNS Check: Pass
Server Up: Pass
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)
Uptime (hrs): Unable to retrieve uptime
Server version: Exchange 2010
Roles: Edge
I know why it does that, but like I said, thanks for the script.
The Real Person!
The Real Person!
Next version is going to just exclude Edge Transports for the time being. Between firewalls and permission issues there is a lot to take into account for testing the Edge role.
Pingback: Outlook Experienced an Internal Error Loading the SSL Libraries
Hi Paul. When I run the script (which is great thank you) I get an error, which I thought was because we have a number of passive servers, but I hope you can clarify.
We have 5 servers in our Exchange setup accross 2 sites.
Site 1. 1x Client Access, Hub Transport (both roles on one server) – XCAS01
Site 1. 2x Mailbox servers – XEXDB01, XEXDB02
Site 2. 1x Client Access, Hub Transport (both roles on one server) – BCAS01
Site 2. 1x Mailbox server – BEXDB01
Site 2 is a DR site.
When I run this script and generate the email, the 2 CAS servers report a few services, including Mail Flow Test as n/a. The 3 Mailbox servers fail the Mail Flow test. At first I thought this was because we have passive servers, but not all 3 are passive.
From in the Exchange Management Console, currently XEXDB02 has the mailboxes mounted. The other 2 report that the Copy Status is healthy.
From this information it may not be possible to provide accurate advice, but any advice is appreciated as to if this is normal behaviour or not.
Cheers, Shane.
The Real Person!
The Real Person!
Hi Shane, I’ve got that one on my bugs list. Should be pretty simple to stamp out in the next version.
Hi Paul,
That’s great to hear, because like Shane, we’ve been experiencing the exact same problem and have had to abandon using the script for the time being as it’s giving too many incorrect results, particularly as it relates to mailflow on MBX servers.
Kerry
The Real Person!
The Real Person!
Yep, stay tuned Kerry. Hoping to have an update out soon.
This is the fun part, when the scripts get run outside of my limited test environments and the bug reports roll in 🙂
Ahh thanks Paul (and Kerry, glad to hear it’s not me being a doofus). I planned to schedule this in an email which is delivered to a mailbox that the Helpdesk team check.
I may put that in place, but let them know not to be alarmed by the red error squares, then update things when the bug is ironed out 🙂
Cheers, Shane.
I was thinking about doing a similar thing Shane, but I reckon it could lead to a bit of the “boy who cried wolf” syndrome.
Y’know, the possibility that once the bug is ironed out, they pay no attention to an alert because they’ve seen so many already, that they ignore what ends up being a genuine problem?
Kerry
Yep I’ve put it on hold until the bug is removed 🙂
No point flooding the Helpdesk with information to ignore.
The mail flow test fails for me too. I have two sites, with an active mailbox server on one site and a passive mailbox server on the other site.
One other thing to ask before turning my attention elsewhere.. we also use a powershell script to check on the health of the databases. I am not much of a coding guru 🙁 and can’t figure out how to include the following into the html report:
function Get-DatabaseStatistics {
$Databases = Get-MailboxDatabase -Status
foreach($Database in $Databases) {
$DBSize = $Database.DatabaseSize
$MBCount = @(Get-MailboxStatistics -Database $Database.Name).Count
$MBAvg = Get-MailboxStatistics -Database $Database.Name |
%{$_.TotalItemSize.value.ToMb()} |
Measure-Object -Average
New-Object PSObject -Property @{
Server = $Database.Server.Name
DatabaseName = $Database.Name
LastFullBackup = $Database.LastFullBackup
MailboxCount = $MBCount
“DatabaseSize (GB)” = $DBSize.ToGB()
“AverageMailboxSize (MB)” = $MBAvg.Average
“WhiteSpace (MB)” = $Database.AvailableNewMailboxSpace.ToMb()
}
}
}
Get-DatabaseStatistics | Export-Csv c:windowstempreport.csv -Force -NoType
Send-MailMessage -To *********@yourdomain -From *********@yourdomain -Subject “Mailbox Database Statistics for $((get-date).ToShortDateString())” -SmtpServer yoursmtpserver -Attachments c:windowstempreport.csv
Can’t remember where i got the script so all kudos go to the original author whoever it may be. The report is exported to csv and then mailed but it would be really awesome to have the two scripts combined in a report html that displays the health of the mail servers and the databases they contain.
Excellent script Paul. I am getting a nice report in my mailbox. I do have one error in the execution of the script. I get the following error in the shell:
Cannot convert value “Unable to retrieve uptime” to type “System.Int32”. Error: “Input string was not in a correct form
at.”
At C:********ToolsTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1:683 char:19
+ $hours = [int] <<<< $($reportline."uptime (hrs)")
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
What do i need to change in the script or my environment to make that part work? Running a Exchange 2010 DAG setup here.
Hi Paul,
Mine works and does its thing but I can’t seem to get the report to be emailed to me.
I’m running this directly on the exchange server.
Here is the error I get.
Exception calling “Send” with “1” argument(s): “Failure sending mail.”
At C:scriptsTest-ExchangeServerHealth.ps1:795 char:13
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
The Real Person!
The Real Person!
That error indicates you haven’t updated the $smtpServer variable in the Email Settings section of the script with a valid entry for your network. Could you double check that please?
I am getting error for Edge Server(DMZ) access denied.How to proceed further
Thanks for sharing this script.
I thought the DNS check was clever, but it didn’t report failed when it probably should have. This week we had 2 forward DNS records that got deleted and the System.Net.DNS check still reported it pass. I’m guessing once queried, its cached locally onto that machine? I ran ipconfig /flushdns which it properly failed after that. Any way to always directly query the DNS server or something else rather than having to run flushdns?
Also, just curious if you have a reason or preference on using System.Net.NetworkInformation.Ping over cmdlet Test-Connection?
Thanks again!
The Real Person!
The Real Person!
Hi Nate, interesting scenario on that DNS check. I’ll see if there is a practical way to account for it.
As for the ping method, when this script was originally born it was in PowerShell 1.0. Later when I tried to use Test-Connection I ran into a weird crashing issue further along in the script and traced it back to the use of Test-Connection.
Some day I hope to get to the bottom of it, or maybe PS 3.0 will solve it for me 🙂
Thanks, I ended up using the function forward_lookup from http://meanderingmarcus.wordpress.com/tag/dns/. I slightly revise to report either pass or fail. This worked perfectly for me. This will tell me if its not in DNS, or if it can’t query DNS (DNS server down).
Hi Paul! great script! works great and quick! I have an issue emailing the report, I get the following error.
Exception calling “Send” with “1” argument(s): “Failure sending mail.”
At E:reportsscriptsTest-ExchangeServerHealth.ps1:796 char:13
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
I read the fix above but that didn't work, any ideas?
Hi Paul, not sure if you missed this issue….
The Real Person!
The Real Person!
I’ll look into it. Is there any other error details that is provides?
Have you changed the script variables to point to a valid SMTP server?
Yes, it is pointing to the correct smtp server now. Thanks Paul! that corrected it. I had it pointing to the mbx server.
Hello Paul.
I have the same issue as previously mentioned. Single Exchange server 2010 SP1 RU6 running on Windows 2008 R2 SP1 in Hyper-V.
[PS] D:scripts>.TestExchangeServerHealth.ps1 -reportmode:$true -sendemail:$true
WARNING: Active Directory server settings remained unchanged.
—— Checking SSTMAIL
DNS Check: Pass
Server up: Pass
Uptime (hrs): 147
Server version: Exchange 2010
Roles: Mailbox, ClientAccess, HubTransport
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 0
Public Folder databases mounted: Pass
Mailbox databases mounted: Pass
MAPI connectivity: Pass
Mail flow test to SSTMAIL Success
Exception calling “Send” with “1” argument(s): “Failure sending mail.”
At D:scriptsTestExchangeServerHealth.ps1:795 char:13
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Thank you for pointing me out, where could be the error. The HTML report is generated. I can find it on the drive in the path where it should be.
BR
Jan
I have managed to get my health report to work against only my servers and not the entire org.
instead of using the array command against mailboxserver etc, use the get-exchangeserver command with the pipes to the required where clauses, such as:
get-exchangeserver | where {$_.name -like “*thisismyserver*”} and so on. “*thisismyserver*” format is the naming convention that you would follow, i.e. you share org with company1 and you are company2, so therefore “*thisismyserver*” would look like this “*company2*”.
Instead of using the array part again the dag, using where clauses again, targeting only your’s and it works.
I still get some errors regarding the services not being able to be checked.
Paul many thanks once again, also edited where the DAG details are and i am targeting only my dag and not all the others.
Hope this help others.
Paul,
when i run the script using SCHEDULE, i get ERRORS on the result email pointing that CA, HT and MB services are not running.
However this errors are not present when I run the script from PS window, everything shows in GREEN (PASS).
The schedule is setup using your instruction as given in SET-AUTOMATED-EXCHANGE….. tutorial.
the action is set to:
-command “c:scriptstest-exchangeserverhealthtest-exchangeserverhealth.ps1 -reportmode $true -sendemail $true”
BRGDS
Marco
Reposting same issue:
Script running fine from PS command , everything shows in GREEN, but on the email message I get error:
“Required services not running. Required services not running. Required services not running.”
reffering to CA Services:Fail; HT Services:Fail; MB Services:Fail.
What am I doing wrong?
BRGDS
Marco
The Real Person!
The Real Person!
Are your servers running a non-English language?
No, EXCHANGE and the Server2008 are English.
the local settings are Danish.
The Real Person!
The Real Person!
Marco, could you send me an email to paul@practical365.com, if you don’t mind I’d like to test a few things with you to work out how to make the script work for systems in other languages.
I’ve got the same problem, when i run the script from the shell CA and HT Services says Pass. When i schedule the same script it says Fail on CA and HT.
I’m running English Windows 2008 and English Exchange 2010 but the locale on Windows is Swedish.
using the ignorelist i get this error just after it check each one of my servers:
Cannot convert value “1 422” to type “System.Int32”. Error: “Input string was not in a correct format.”
At C:TempTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1:261 char:18
+ [int]$uptime <<<< = "{0:N0}" -f $uptime
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
The Real Person!
The Real Person!
Seems to be having trouble with the uptime calculation for some reason. I can try and reproduce the bug, but can you give me a clue how long its been since the last time your servers were restarted?
Paul, I have seen this as well for the tests against edge servers that are either not on the domain or have restricted access through firewalls from the core network. As a result queries cannot be completed, although in the html report the uptime value seems to be being entered as the same as the previous server in the table due to the conversion error.
The Real Person!
The Real Person!
I’ll try and fix that uptime value issue but for now its probably better just to add Edge servers to the ignorelist.txt
Hi,
Got it as “inheritance” guess i can just set it to be Auto and Running.
Thanks.
Hi,
I see it’s because we don’t use Edge and script check for it’s service:
Role : Hub Transport Server Role
RequiredServicesRunning : False
ServicesRunning : {IISAdmin, MSExchangeADTopology, MSExchangeServiceHost, MSExchangeTransport, MSExchangeTransp
ortLogSearch, W3Svc, WinRM}
ServicesNotRunning : {MSExchangeEdgeSync}
Can we skip it?
Thx.
The Real Person!
The Real Person!
What is the status of the service? Have you set it to manual or disabled?
My servers, even those not involved in EdgeSync, have it Automatic + Running at the moment.
Disable
The Real Person!
The Real Person!
Any particular reason? It can be Auto and Running even if there is no Edge servers. That will clear up that error with the Test-ServiceHealth part of the script.
Hi, Great script, thanks a lot.
My environment is EX2010&07, anyone has a clue why i get
“Hub Transport Server Role Services: Fail” on all CASHUB servers.
Regards,
Rafi.
The Real Person!
The Real Person!
Please run Test-ServiceHealth on one of those servers and paste the results here.
Hi Paul, thanks, here it is, same for all HUB|CAS servers, services up and running.
—— Checking xxxx
DNS Check: Pass
Server up: Pass
Uptime (hrs): 572
Server version: Exchange 2010
Roles: ClientAccess, HubTransport
Client Access Server Role Services: Pass
Hub Transport Server Role Services: Fail
Total Queue: 0
The Real Person!
The Real Person!
Please run Test-ServiceHealth
after a little bit of fiddling i got it to work, but now get an error, not sure if this is due to my changes.
below is the error from the shell:
DNS Check: Pass
Server up: Pass
Cannot convert value “2 961” to type “System.Int32”. Error: “Input string was not in a correct format.”
At C:TempTest-ExchangeServerHealth.ps1:261 char:18
+ [int]$uptime <<<< = "{0:N0}" -f $uptime
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
Great script once again. Because my exchange environment sits in a shared org, i need to target my servers which have a specific naming convention. Which line etc would i put my “where” clause in?
The Real Person!
The Real Person!
Stay tuned, I’m going to update it with some options for being more specific with the servers you test.
I have also tried to change:
$exchangeservers = “server1″,”server2” etc
it still runs through all items in the org and not just check my servers.
The Real Person!
The Real Person!
Perhaps you’ve changed the wrong line. If this was the line you changed…
$exchangeservers = Get-ExchangeServer $server -ErrorAction Stop
…that is not the correct one. The script was written with your scenario in mind so suggesting a code change here in the comments is getting a bit tricky in this case.
I’ll update the script this week with the option to specify a file containing a list of servers to check, but in the meantime I’d suggest just using the ignorelist.txt file to exclude the ones you don’t want to check.
Hi Paul – I’m after something similar with the opposite of the ignore list – the latest version of your script references this a servierlist but doesn’t have any line that references what the file is called or where it is located in the same way the ignore list was. Thanks, Matt
The Real Person!
The Real Person!
You can use -ServerList and then specify the name of the file containing your list of Exchange servers. You have to provide the name of the file, the script won’t go looking for a specific file name by default.
The one caveat is that if you use -ServerList the DAG checks are skipped. That isn’t ideal for everyone, I know, but it’s a carry over from legacy code.
may bad, yes i did edit wrong line. working now 🙂
i still get this though just after the “server up” item:
Cannot convert value “2 968” to type “System.Int32”. Error: “Input string was not in a correct format.”
At C:TempTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1:262 char:18
+ [int]$uptime <<<< = "{0:N0}" -f $uptime
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
is this what you will be looking at in a fix?
Hi Paul,
Great script, but I’d really like to see a few extra features added if possible.
In your original version of this script, you included a check of the DAG and its copies. Any chance that could be added back into this new version?
Likewise, one of the things we’ve found important to keep an eye on is that all server nodes are seeing all DCs and GCs at all times. We do this by looking at Server Configuration > Server Name > System Settings tab
If both of these features could be included in your script, it would be hugely helpful.
Kerry
The Real Person!
The Real Person!
I’ll work on those features, thanks for the feedback.
Thanks so much, Paul.
Keep up the great work. Your new MVP status is well deserved.
thanks mate,
i was just unblocking when i got your reply 🙂
thanks a million 🙂
Got a weird one for you Paul.
I’ve set up a second scheduled task using a slightly modified version of the script .. simply saying “alert” rather than “health check” and with the EXIT added so that if no errors are found, I get no email report.
Anyway, I keep getting an error on the CA Services on one of my CAS, but if I run “Test-Servicehealth” in Powershell on the server in question, it’s showing that necessary services are running as normal.
I should also mention that this error does not show in the standard Health Check report, but does show in the ALERT with the EXIT added. The script is scheduled to run on the same server that’s showing the error.
I’m wondering if you might have any thoughts on what might be happening and how to fix it?
Never mind, Paul. I went back and checked and double-checked my tiny changes, and things are now working as expected with both Scheduled Tasks. The script report is now delivering accurate results.
Hi Paul,
Excellent script, well done.
i do have a question though, your previous script “How to Set Up an Automated Exchange 2010 Database Backup Alert Email” was followed to the T and it works.
however, when i try and schedule task this one, i keep getting the ExecutionPolicy error asking me to confirm if i want to run the script. i understand that i have have to Set-ExecutionPolicy Unrestricted, but was wondering if there is an easier way to do this before the script runs ?
Cheers 🙂
The Real Person!
The Real Person!
Should be able to just set it once and it will stick… unless you’ve got a GPO or something reverting it?
Hi Paul, Thanks for getting back.
I have set the execution policy to unrestricted and i’m still getting prompted.
this is the command i’m running
.Test-ExchangeServerHealth.ps1 -reportmode $true -Sendemail $true
this is what i get even after 30 seconds of running Set-ExecutionPolicy Unrestricted
Security Warning
Run only scripts that you trust. While scripts from the Internet can be useful, this script can potentially harm your computer.
Do you want to run C:scriptsTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is “D”):
The Real Person!
The Real Person!
You may need to right-click the downloaded file and in the properties unblock it.
Setting an execution policy of unrestricted for PowerShell in my view is a very bad idea (although I understand you might do so temporarily). I’d recommend the following process for all scripts dowloaded:
– Set Execution no lower than remote signed
– Dowload the script and review the contents, if you aren’t familiar with PowerShell search for set-, new-,add- type cmdlets and if they exist I wouldn’t run the script unless I understood what it is doing as these cmdlets usually change something, get- is fine as it is read-only
– If possible test in a DEV environment after taking the step
– Create a new text file then copy and paste the original downloaded file contents to the new text file. Then save the new text file with a ps1 file extension.
The above process will mean that you are better protected from malware by lowering the execution policy to a dangerous level.
Paul
Dear Paul,
Thanks your script, very nice job!. Currently, I has set the script by using windows task schedule with batch file:
C:WindowsSystem32WindowsPowerShellv1.0powershell.exe -command “. ‘C:Program FilesMicrosoftExchange ServerbinRemoteExchange.ps1’; Connect-ExchangeServer -auto; F:PSScriptTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true”
I can run batch file and receive html email, but when I’ve run task schedule manually, the scheduled task reports with error: The task currently running. (0x41301). I cannot get any results until I stopped. Whats wrong with my configuration?
Task schedule
https://www.practical365.com/set-automated-exchange-2010-database-backup-alert-email
Cheers 🙂
The Real Person!
The Real Person!
What credentials is the scheduled task configured to run as?
I use domain admin for testing.
http://social.technet.microsoft.com/Forums/en-US/winservergen/thread/6e333a49-f04e-4e4e-9ac6-66fd0802859e/
Anyway, I modified batch file and the problem has been resolved with out “Add-PSSnapin”
powershell.exe -command “. ‘C:Program FilesMicrosoftExchange ServerbinRemoteExchange.ps1′; Connect-ExchangeServer -auto; F:PSScriptTest-ExchangeServerHealthTest-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true”
Thanks Paul for your reply!
The Real Person!
The Real Person!
Ah okay I see. Yes the script calls the Exchange snapin itself, so your scheduled task should be able to just run the script without having to first load RemoteExchange.ps1
Hi Paul!!
I’m having this problem.
Função de Servidor Caixa de Correio Services: Pass
Add-Member : Não é possível associar o argumento ao parâmetro ‘Name’ porque ele é nulo.
Em C:ScriptsTest-ExchangeServerHealth.ps1:344 caractere:52
+ $serverObj | Add-Member NoteProperty -Name <<<< $roleservices -Value $svchealth
-Force
+ CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCo
mmand
The Real Person!
The Real Person!
I would say this is simply a language issue, and the script is checking for a string match in English.
I’ll try to include a fix in the next update.
Tnkssssssssssssssssssss Paul!!!!!!!
I have the same problem with a french version. Do you have a solution?
Thank you.
Add-Member : Impossible de lier l’argument au paramètre « Name », car il a la valeur Null.
Au niveau de C:adminTest-ExchangeServerHealth.ps1 : 358 Caractère : 52
+ $serverObj | Add-Member NoteProperty -Name <<<< $roleservices -Value $svchealth
-Force
+ CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCo
mmand
The Real Person!
The Real Person!
Not yet sorry.
Do you have a solution for this problem?
The Real Person!
The Real Person!
Yes, the fix was added to the script some time ago.
Regarding the errors on Exchange-Server in other languages:
You have to change the lines 346-349, where there are only the english server-role-names.
In the output with the error-messages, you can see the name of the roles in your own language, e.g in german:
“Hub-Transport-Serverrolle Services: Pass
Add-Member : Das Argument kann nicht an den Parameter “Name” gebunden werden, da es NULL ist….”
So you must change (or add lines) e.g. on german exchange-server:
“Clientzugriff-Serverrolle” { $roleservices = “CA Services” }
“Hub-Transport-Serverrolle” { $roleservices = “HT Services” }
“Mailbox-Serverrolle” { $roleservices = “MB Services” }
“Unified-Messaging-Serverrolle” { $roleservices = “UM Services” }
instead of(or additional to):
“Client Access Server Role” { $roleservices = “CA Services” }
“Hub Transport Server Role” { $roleservices = “HT Services” }
“Mailbox Server Role” { $roleservices = “MB Services” }
“Unified Messaging Server Role” { $roleservices = “UM Services” }
Additionally you must change the following line:
if ($testmailflowresult -eq “Success”)
to your own language, e.g. on german Exchange Server:
if ($testmailflowresult -eq “Erfolgreich”).
You can find the correct word of your language also in the output before you have fixed it:
Public Folder databases mounted: Pass
Mailbox databases mounted: Pass
MAPI connectivity: Pass
Mail flow test: Erfolgreich
After these changes the script works fine for my german exchange organisation
In spanish too
Great script and very useful! Congratulations becoming an MVP, nice job!!
Hi Paul,
thanks for another useful script.
It runs fine though i do get one scary message right at the beginning of running the script:
I’ve found that the following line:
Set-ADServerSettings -ViewEntireForest $true -WarningAction SilentlyContinue
Generates the error message:
WARNING: Active Directory server settings remained unchanged.
After REMing the line out I don’t get the error message and the script continues to run fine. As I’m only interested in one domain I don’t think removing that line is going to make any difference to me.
Cheers 🙂
The Real Person!
The Real Person!
Thats just a warning that the setting was already at $true. If your forest only has one domain then you don’t need that line anyway.
In my environment running the script interactively from a CAS and pointing the SMTP server variable at a hub I get the following error:
Exception calling “Send” with “1” argument(s): “The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated”
I’ve come across this before and it can be cured with an additional line that forces authentication. The current line:
#Send email message
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
becomes
#Send email message
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.UseDefaultCredentials = $true
Hope this might help others
Paul
The Real Person!
The Real Person!
Good catch. I’m used to pointing mine at SMTP servers that are already configured for anonymous users, or at a DNS alias for a relay connector that allows anonymous users.
Exception calling “Send” with “1” argument(s): “The SMTP server requires a secure connection or the client was not auth
enticated. The server response was: 5.7.1 Client was not authenticated”
At E:Manual ScriptsTest-ExchangeServerHealth.ps1:797 char:13
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Thanks it works for me
I can’t find this line to add to the script!
Could any one inform which line is it?
Thanks
Thank you so much. It saves me a ton of nose hairs :=)
It works.
Is it possible to run this script against a list of servers? I don’t want to run it against every exchange server in my organization, just the ones on a specific list.
The Real Person!
The Real Person!
Yes. There are two ways you could achieve that.
1) Use the ignorelist.txt file to exclude specific servers.
2) Modify the $exchangeservers variable so that it only includes the servers you want to check
eg,
$exchangeservers = “server1″,”server2″,”server3”
Thanks. It is now running through the list of servers but after it finishes the list it keeps going. Do I need to put something at the end of the list of servers?
The Real Person!
The Real Person!
What do you mean “it keeps going”?
Once it finishes running through the servers on the list it starts doing the other servers in my organization.
The Real Person!
The Real Person!
When you modified $exchangeservers did you replace the existing line of code that sets that variable, or did you add it as an extra line?
Anyway, I’ll add a parameter to the next version to allow you to specify a filename containing a list of servers to check.
Hi Paul,
Thanks for such a nice script.But have some queries, i wanted to run a script on multiple servers at a time how can i achieve that using the option “-ServerList” .
How to pass the server names….please help
I replaced the line. Does the list of servers need to be in brackets or anything?
Being able to to use a file with the server names is great feature. I will watch out for the next version. Thanks.
very nice script, thankyou.
How would I modify it so that it only emails if there is a fail detected ?
I plan to run the script as a scheduled task every 15 minutes.
thanx again.
Ray.
The Real Person!
The Real Person!
On line 625 there is this:
$summaryhtml = “< h3 >Exchange Server Health Check Summary h3 >
< p >No Exchange server health alerts or warnings. p >”
Since that is basically the scenario where no fails were found, adding an EXIT right after that should end the script execution before the email is sent.
Not the most elegant solution but probably the fastest one I can offer you.
Thanx Paul. that worked. cheers.
I’ve also added a line to amend the subject at this point.
$messageSubject = “Failure: ” + $messageSubject
This way our noc/alerting software can keep an eye out for the failures and ignore the successful ones. (we actually escalate emails where the subject line contains Failure
I’m using the EXIT to stop the script if there is no issues, but it still sends the email. I’m I putting the EXIT in the right spot?
$summaryhtml = “Exchange Server Health Check Summary
No Exchange server health alerts or warnings.”
} EXIT
The Real Person!
The Real Person!
I will likely include an option in the next version to only email when alerts are detected.
Great script and one I’ll probably use at work. Out of interest do you have a developer background or are you a self taught scripter? I like the aesthetic layout of your scripts as it makes them easy to read, you also tight define variables but you tend not to use functions.
Although I am quite happy scripting, I taught myself and am concerned I could structure my efforts better than I do.
Paul
The Real Person!
The Real Person!
Hi Paul, I’m mostly a self taught scripter, no developer background.
I write the code in a way that makes it easy for me to read and understand if I have to come back to it later. There is no point wasting effort writing code that you can’t understand when you need that code again, or want to modify it 🙂
Running on Exchange 2007 SP1
The Real Person!
The Real Person!
If you run it from a separate management server or workstation that has PS 2.0 and the Exchange 2007 management tools installed that is another way to resolve the PS 2.0 issue. Or just remove the PS 2.0-syntax comments at the start of the script as suggested earlier.
There is one Exchange 2007 server in my test lab where I ran the script to make the video above, but I haven’t thoroughly tested it or coded it with Exchange 2007 in mind so I can’t guarantee it will work.
Let me know how you go.
I think I am getting this error because I am running this on PowerShell V1.0. This script is made to run on PowerShell v2.0
Please can you modify this script to run on Powershell V1.0.
The Real Person!
The Real Person!
All the comments at the start of the script are in the PS 2.0 syntax. If you remove all those it will probably fix that initial problem, but I don’t plan to make it PS 1.0 compatible otherwise.
What version of Exchange are you trying to run it for? It is written for Exchange 2010.
When I run this script i get this error:
[PS] C:WindowsSystem32>Test-ExchangeServerHealth.ps1
Missing closing ‘)’ in expression.
At C:WindowsSystem32WindowsPowerShellv1.0Test-ExchangeServerHealth.ps1:56
char:2
+ [ <<<< string]$server,
Please help me correct this.
Regards
Philip
Fantastic! I have been looking around for an “all-in-one” health script.
BTW: Congrads on your MVP.
Thanks Paul! Another great script as always.. one to add to the daily automated list.
The new script look like it doesn’t inlcude the DAG copy status check (in the original version).
The Real Person!
The Real Person!
I’ll work on adding that back in.
He Paul,
I need the latest exchange health check script from you.
I downloaded one but unable to execute it.
Do I need to change anything in the script.
Regards,
Saroj
The Real Person!
The Real Person!
What does “unable to execute it” mean? Do you get an error? Have you followed the instructions that are provided with the script?
Hi Paul,
I am Unable Run this scripts as a Scheduler in ExchangeServer2016, But when i run Manually it is working fine.
[PS] C:\Users\Administrator.Local\Desktop\Test-ExchangeServerHealth>.\Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
Initializing…
WARNING: The file C:\Users\Administrator.GVA\Desktop\Test-ExchangeServerHealth\ignorelist.txt could not be found. No
servers, DAGs or databases will be ignored.
—— Checking EX01
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 2
Server version: Exchange 2016
Roles: Mailbox
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 0
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: Success
—— Finishing
Sending email.
Done.
[PS] C:\Users\Administrator.Local\Desktop\Test-ExchangeServerHealth>
Can you please some one create Scheduler as above my path and Export the settings to send me?
Regards
TLS
Hi Paul,
I also stuck here. I unable to run health check using Task Scheduler.
Windows Server OS 2012 R2
According to your above article steps not working:
Run whether user is logged on or not
Run with highest privileges
Action: Start a program
Program: powershell.exe
Arguments: -command “C:\Scripts\ExchangeServerHealth>Test-ExchangeServerHealth.ps1 -Log -SendEmail”
Cheers,
Allen
The Real Person!
The Real Person!
Arguments has an error. Should be a \ instead of the >
Hi Paul,
Here below is my scripts
-command “& ‘C:\Scripts\ExchangeServerHealth\Test-ExchangeServerHealth.ps1’ -Log -SendEmail”
I still unable to run from Task Scheduler, here from Log file I can see it just stuck @ loading Exchange Server PowerShell snapin
Do you know the reasons? But, It can generate if I just copy and run manually from PowerShell Window with exact word.
06/27/2018 17:02:38 =====================================
06/27/2018 17:02:38 Exchange Server Health Check
06/27/2018 17:02:38 06/27/2018 17:02:37
06/27/2018 17:02:38 =====================================
06/27/2018 17:02:38 Initializing…
06/27/2018 17:02:38 Loading the Exchange Server PowerShell snapin
The task will just show running until I manual cancel the job.
Please Help.
Thanks.
Best Regards,
Allen
The Real Person!
The Real Person!
Is the schedule task running with the same credentials you’re using when you manually run the script?
Hi,
I had the same problem. I was able to run the script manually but from schedule task it was failing. I used the below and it worked for me.
Action: Start a Program
Program/Script: Powershell.exe
Add arguments (optional): -File “C:\script\Test-ExchangeServerHealth.ps1” -ReportMode -SendEmail
Start in (optional): blank
Thanks,
Hi Paul,
Will I be lucky to add your skype?
To exchange experiences with each other.
I am Tony, from Vietnam.
Thanks,
IT Manager
Tony
It would be nice if there were an actual link to download the script.
If you can’t find it, you don’t belong anywhere near an Exchange server
I have to say Thank you First Paul for this amazing script. I do have a problem I want to clarify with you. On my test which I can’t show the picture of it.. It shows Mail Flow test as failed the same with Database Redundancy and Database Availability.. The rest is all Green Passed.. I don’t have any issues with my DAG or my mail flow.. So not sure why is this happening.
I’m having this issue too. Script says failed on all but my 2010 mailbox (not CAS & hub transport) server, but mail is flowing fine.
The Real Person!
The Real Person!
The mail flow test for 2013 and later relies on a PS remoting connection, which is a bit of a hack to get around problems with Test-MailFlow in those versions. It will fail if there’s a problem with the remoting connection. See my other reply to your other comment.
Hi Paul,
I have the same problem. Can you please clarify a little bit how this can be fixed?
Cheers
Dirk
Hi Paul
When i run this file, it’s OK. But when i create a task schedule, it doesn’t complete. I check log file, it stop at ” Loading the Exchange Server PowerShell snapin”:
01/04/2018 11:50:14 =====================================
01/04/2018 11:50:14 Exchange Server Health Check
01/04/2018 11:50:14 01/04/2018 11:50:14
01/04/2018 11:50:14 =====================================
01/04/2018 11:50:14 Initializing…
Please you help me to check
Many thanks!
01/04/2018 11:50:14 Loading the Exchange Server PowerShell snapin
Hi I am Unable this scripts on Scheduler in ExchangeServer2016, But when i run Manually it is working fine.
[PS] C:\Users\Administrator.Local\Desktop\Test-ExchangeServerHealth>.\Test-ExchangeServerHealth.ps1 -ReportMode -SendEmail
Initializing…
WARNING: The file C:\Users\Administrator.GVA\Desktop\Test-ExchangeServerHealth\ignorelist.txt could not be found. No
servers, DAGs or databases will be ignored.
—— Checking EX01
DNS Check: Pass
Ping Check: Pass
Uptime (hrs): 2
Server version: Exchange 2016
Roles: Mailbox
Mailbox Server Role Services: Pass
Client Access Server Role Services: Pass
Unified Messaging Server Role Services: Pass
Hub Transport Server Role Services: Pass
Total Queue: 0
Mailbox databases mounted: Pass
MAPI connectivity: Success
Mail flow test: Success
—— Finishing
Sending email.
Done.
[PS] C:\Users\Administrator.Local\Desktop\Test-ExchangeServerHealth>
Can you please some one create Scheduler as above my path and Export the settings to send me?
Regards
TLS