Get-DAGHealth.ps1 – Database Availability Group Health Check Script

Since I released the Test-ExchangeServerHealth.ps1 script one of the most common feature requests has been to add health checks for Database Availability Groups.

So today I am pleased to announce the availability of Get-DAGHealth.ps1, a Database Availability Group health check PowerShell script.

This is the first release to your feedback and bug reports are welcome in the comments below. I hope to eventually merge this with the Test-ExchangeServerHealth.ps1 script to provide a single, daily health check script that you can use for your Exchange environments.

Please read the usage instructions in below or in the script help info.

6754 downloads so far.
This script is available for download by Exchange Server Pro Insiders. Join here it’s free.

Running Get-DAGHealth.ps1

The script is written and tested for Exchange Server 2010 and Exchange Server 2013 CU1.

The script requires the Exchange Management Tools to run. You can execute it from the Exchange Management Shell, or a regular PowerShell session and it will add the Exchange snapin if not already loaded.

You can also execute it as a scheduled task. I use the follow settings in my scheduled task to make it work:

  • Run whether user is logged on or not
  • Run with highest privileges
  • Action:
    • Start a program: powershell.exe
    • Arguments: -command “c:\scripts\daghealth\get-daghealth.ps1 -Detailed -SendEmail”
  • You may need to modify your script execution policy to run this script as it is not signed
  • You may need to open the Properties of the downloaded file and “unblock” it before it will run

Use Get-Help to see more usage details and examples.

PS C:\Scripts\DAGHealth> get-help .\Get-DAGHealth.ps1 -Examples

NAME
    C:\Scripts\DAGHealth\Get-DAGHealth.ps1

SYNOPSIS
    Get-DAGHealth.ps1 - Exchange Server 2010 Database Availability Group Health Check Script.

    -------------------------- EXAMPLE 1 --------------------------

    C:\PS>.\Get-DAGHealth.ps1

    Checks all DAGs in the organization and outputs a health summary to the PowerShell window.

    -------------------------- EXAMPLE 2 --------------------------

    C:\PS>.\Get-DAGHealth.ps1 -Detailed

    Checks all DAGs in the organization and outputs a detailed health report to the PowerShell
    window. Due to the amount of detail the full report may get cut off in your window. I recommend
    detailed reports be output to HTML file or email instead.

    -------------------------- EXAMPLE 3 --------------------------

    C:\PS>.\Get-DAGHealth.ps1 -Detailed -SendEmail

    Checks all DAGs in the organization and outputs a detailed health report via email using
    the SMTP settings you configure in the script.

I generally recommend using the HTML file or email output to get the best results. The HTML output gives a color-coded health report to bring to your attention any potential health issues such as databases not active on their first preference server, unhealthy copies or queues, unhealthy content indexes, and other things that can sometimes go unnoticed with DAGs.

get-daghealth-output

The report is indicative only. You should investigate and validate any issues that it flags to determine what if any action is required to resolve them.

6754 downloads so far.
This script is available for download by Exchange Server Pro Insiders. Join here it’s free.

Change Log:

  • V1.0 – 14/02/2013 – Initial release
  • V1.1 – 24/04/2013 – Bug fixes, Exchange 2013 compatibility

Feedback and bug reports welcome in the comments below. If you like this script please feel free to share this article with your friends and colleagues on Twitter, Facebook, LinkedIn, Google+ etc. You might also be interested in some of my other PowerShell scripts.

Comments

  1. Patrick Dunnigan says

    I’m trying to run the DAG Heath Report on the same server I have your previous Health Check report running. When I run the Dag Report, Powershell gives me the following errors, any ideas?

    Update-TypeData : The following error occurred while loading the extended type data file:
    Microsoft.PowerShell, C:\Program Files\Microsoft\Exchange Server\V14\bin\exchange.types.ps1xml : File skipped because i
    t was already present from “Microsoft.PowerShell”.
    At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.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, C:\Program Files\Microsoft\Exchange Server\V14\bin\Exchange.partial.Types.ps1xml : File skipped b
    ecause it was already present from "Microsoft.PowerShell".
    Microsoft.PowerShell, C:\Program Files\Microsoft\Exchange Server\V14\bin\exchange.types.ps1xml : File skipped because i
    t was already present from "Microsoft.PowerShell".
    At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:104 char:16
    + Update-TypeData <<<< -PrependPath $partialTypeFile
    + CategoryInfo : InvalidOperation: (:) [Update-TypeData], RuntimeException
    + FullyQualifiedErrorId : TypesXmlUpdateException,Microsoft.PowerShell.Commands.UpdateTypeDataCommand

  2. Alex C says

    Thank you very much, Paul, for sharing your work! Awesome! :)
    For your information, and I guess you already know, when running the script, the following errors are displayed, though the script is executing perfectly.

    Update-TypeData : The following error occurred while loading the extended type data file:
    Microsoft.PowerShell, D:\Program Files\Microsoft\Exchange Server\V14\bin\exchange.types.ps1xml : File skipped because it was already present from “Microsoft.PowerShell”.

    Update-TypeData : The following error occurred while loading the extended type data file:
    Microsoft.PowerShell, D:\Program Files\Microsoft\Exchange Server\V14\bin\Exchange.partial.Types.ps1xml : File skipped because it was already present from “Microsoft.PowerShell”.

    I was running the script in a normal EMS session.
    Thanks again!
    Cheers,
    Alex

  3. ram says

    Hi Paul

    This script is really awesome and am huge fan of you

    Only one Flow which i found is , if the DB is moved or failover from one server to another server

    can it be show like

    DBName on server2 should be on Server1

    what am trying tell is DB is server1 , due to some N/w issue and the DB was moved and sitting on Server 2

    can this report show like DBName on server2 should be on Server1

    or am i missing the information in this report.

    • says

      The script doesn’t attempt to diagnose in detail or recommend a specific action be taken. It is intended to present you enough details of possible issues so that you can make decisions about how to remediate problems.

      So in the case of databases not being on their activation preference 1 server, the script flags that in the summary table, and then in the details table it also tells you which server is AP1 for that DB (but you can easily see that in EMC anyway). So then its up to you whether the DB should be moved or not.

  4. Shane Bryan says

    Just ran it, worked perfectly first time. Scheduled task is in place to run it a few times per day. Not quite at the point where I can sit on the beach 8 hours a day, but getting close thanks to Paul :-p

  5. Scott Brown says

    Hi Paul,

    I am getting the below error when trying to run the script. My be a user error but just wondering if you can help?

    [PS] C:\Install.set>.\Get-DAGHealth.ps1
    The ‘<' operator is reserved for future use.
    At C:\Install.set\Get-DAGHealth.ps1:109 char:51
    + $summaryintro = "Database Availability Group < <<<$($dag.Name) Health Summary:”
    + CategoryInfo : ParserError: (<:OperatorToken) [], ParseException
    + FullyQualifiedErrorId : RedirectionNotSupported

  6. says

    Super! Very usefull and great script. Thank you very much.

    Little bug report:
    1. I’m also get Update-TypeData error ( http://pastebin.com/putBAuAu ) on first run of script as Alex C.
    2. Because of Russian date and time formats on server I get email with question marks instead of month name.
    So I added -Encoding parameter to Send-MailMessage commandlet and month name now in russian like it should. Now my command looks like this:
    Send-MailMessage @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF8)

    Thanks again.
    Best regards,
    Oleg.

    • Kusado says

      I’ve just added one line in the if ($SendEmail) block:
      $encoding = [System.Text.Encoding]::UTF8
      No need to add more paramaters to command line.
      Also added more options to switch operators to support russian translation, they now look like
      Switch ($($line.TCPListener))
      {
      $null { $htmltablerow = $htmltablerow + “$($line.TCPListener)” }
      “Passed” { $htmltablerow = $htmltablerow + “$($line.TCPListener)” }
      “Проверка пройдена” { $htmltablerow = $htmltablerow + “$($line.TCPListener)” }
      default { $htmltablerow = $htmltablerow + “$($line.TCPListener)” }
      }

  7. Robert Coggins says

    I am having a hard time getting this to run as a scheduled job where “Run whether user is logged on or not” is selected. It runs just fine with the “Run only when user is logged on”.

    When redirecting output I get:
    VERBOSE: Connecting to myserv1.domain
    VERBOSE: Connecting to myserv1.domain
    VERBOSE: Connecting to myserv1.domain
    VERBOSE: Connecting to myserv1.domain
    Failed to connect to an Exchange server in the current site.

    Any ideas?

        • says

          Could it be the credentials you’re using do not have the required rights? I’ll admit I haven’t put any thought yet into a nice RBAC role for this script and I just run it with a full Org Admin in my test lab for now. I’m wondering if you’re accidentally running it as the local admin on the server or something like that?

        • Robert Coggins says

          First I gave only view only org manager rights but then I gave full Org Man rights. And the script runs as the user when logged in as the user or if I select “Run only when user is logged on”. I will play with it more and will update if I find something.

  8. Diego says

    Great script. I missed only the sort function in line 162 for a optimized view (for the case that the server have different names).

    $tmpservers = @(Get-ExchangeServer) |sort

  9. Kirill says

    Thank you, script is very useful, I testing in my enviroment, and have some questions.

    When i get report on mail, some word looks like ????? for example curent date and PASSED for member health, in yellow bars i see ?????

    I am using russian 2008 r2 and Exchange 2010, where i must fix code page ? Please help.

    Anyway thanks, script realy helps monitor DAG Group

  10. Carsten says

    Great script!

    Is there a way to modify it so that it only sends an email if the script turns up a red flag? That would be really useful.

    • says

      Well, it is PowerShell so of course it can be modified to do anything you like :)

      But consider that the script also checks for a lot of “warning” conditions that aren’t necessarily an error or serious fault but may be something that the administrator wants to be aware of.

  11. Arras says

    Works Perfect!
    Q: On the Health Summary table, Column Preference, it shows 1 Green and the rest of the DB’s 2 Yellow. What does the Yellow represents?
    Thanks.

    Database Mounted on Preference
    DB01 SecondServer 1
    DB02 FirstServer 2
    DB03 SecondServer 2
    DB04 FirstServer 2
    DB05 SecondServer 2
    DB06 FirstServer 2
    DB07 SecondServer 2
    DB08 FirstServer 2
    DBTest SecondServer 2

  12. David says

    Great script, Paul. I added a check for Incremental and Full backups to the “Detailed” switch in your script, but I’m having problems comparing the date to a variable. Any thoughts on what I can do? I can send you the whole script if you want to see how it’s pulled in.

    $incrPass = ((Get-Date).AddDays(-1)).ToString(“yyyy-MM-dd HH:mm:ss”)
    $incrWarn = ((Get-Date).AddDays(-4)).ToString(“yyyy-MM-dd HH:mm:ss”)

    #Warn if Incremental backups have not run recently
    If ($(line.”Last Incremental Backup”).ToString -lt $incrPass)
    {
    $htmltablerow = $htmltablerow + “$($line.”Last Incremental Backup”)”
    }
    Elseif ($(line.”Last Incremental Backup”).ToString -lt $incrWarn)
    {
    $htmltablerow = $htmltablerow + “$($line.”Last Incremental Backup”)”
    }

  13. Keith K. says

    This script is awesome Paul!
    How often do you recommend running this script. Is it safe to run it maybe every hour or once a twice a day? Just want to make sure that it’s not putting any kind of load on my servers. :-)
    Thx.

  14. Javier A says

    Thanks, It works great on my environment
    There´s something Im not sure what it means..

    In the Member Health table from one of my DAGs (got 4) shows “N/A” in the following columns

    DB Copy Suspended
    DB Initializing
    DB Disconnected
    DB Log Copy Keeping Up
    DB Log Replay Keeping Up

    All the other columns in the same table shows “Passed”

    Any idea?

    • says

      That usually indicates the server hosts no passive database copies. It isn’t a problem unless you’re concerned about having a balanced distribution of active/passive copies in your DAG.

  15. Shane Bryan says

    Thanks for the great script Paul. I’ve got it running twice a day, sending an email to our shared IT Team mailbox.

    Top work :-)

  16. Sankar N says

    Thanks you very much for sharing this Awesome script!!…

    can you add few other command to this script like
    1) Get-Counter “\MSExchange Rpcclientaccess\User count”
    2) Get-Counter “\MSExchange owa\Current Unique Users”
    from this command we can monitor that no.of user connection has shared equally among CAS servers.

  17. Obi says

    Great script, worked like a charm. I got the same error that other reported after the initial run, but none afterwards. Great way to keep track of those pesky “failed” indexes

  18. Alex Logan says

    Hi Paul, fantastic script. I just noticed however that after some recent server patching, that I’m getting some false-positves in the HTML output. “Healthy Queues” are all red, but with a value of zero, even though my queues are fine. “Truncation Lagged” and “Content Index” columns are all blank. Any ideas? I’m running 2010 SP2 RU3.

    Thanks again!

    -Alex

  19. Manoj Vijaykumar says

    Awesome script Paul. Really love the report. These colored reports definitely help with the management too. Keep up the great work.

  20. Sorin says

    Hi Paul,

    Did someone reported that Activation Preference information is not shown in the report. This is happening in my case. Otherwise the script return valuable info.

    Here is part of output when using “-verbose”:
    VERBOSE: Retrieving Database Availability Groups
    VERBOSE: 2 DAGs found
    VERBOSE: —- Processing DAG xxxx
    VERBOSE: x DAG members found
    VERBOSE: xx DAG databases found
    VERBOSE: —- Processing database xxxxxxxxxxxxxx
    VERBOSE: xxxxxxxxxxxxxx has 3 copies
    VERBOSE: Database Copy: xxxxxxxxxxxxxx\xxxxxxxxxxxx
    VERBOSE: Server: xxxxxxxxxxxxxx
    VERBOSE: Activation Preference:
    VERBOSE: Status: Healthy
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 1
    VERBOSE: Content Index: Healthy
    VERBOSE: Database Copy: xxxxxxxxxxxxxx\xxxxxxxxxxxxxx
    VERBOSE: Server: xxxxxxxxxxxxxx
    VERBOSE: Activation Preference:
    VERBOSE: Status: Healthy
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 1
    VERBOSE: Content Index: Healthy
    VERBOSE: Database Copy: xxxxxxxxxxxxxx\xxxxxxxxxxxxxx
    VERBOSE: Server: xxxxxxxxxxxxxx
    VERBOSE: Activation Preference:
    VERBOSE: Status: Mounted
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 0

    Thanks a lot.
    Sorin

    • says

      Interesting. Maybe a permissions issue? Using the same credentials can you run this command and tell me whether you see the list of servers and their preferences in the output?

      Get-MailboxDatabase | select name,activationpreference

      • Sorin says

        permissions are fine. Running Get-MailboxDatabase | select name,activationpreference returns correct information:
        Name ActivationPreference
        —- ——————–
        DB1 {[xxxxxxxxxxxx, 1], [xxxxxxxxxxxx, 2], [xxxxxxxxxxxx, 3]}
        DB2 {[xxxxxxxxxxxx, 1], [xxxxxxxxxxxx, 2], [xxxxxxxxxxxx, 3]}
        DB3 {[xxxxxxxxxxxx, 1], [xxxxxxxxxxxx, 2], [xxxxxxxxxxxx, 3]}

  21. TonyH says

    Thanks Paul. It’s come just at the right time for us as we’ve just finished test our new DAG implementation and will be started the DB copies next week. I’ve run it on the test DBs we have in place and all is good so far!

      • says

        Thanks Paul for yor reply,

        I get the following results;

        Database Mounted on Preference
        DB1 HO-MCH-01 1
        DB2 HO-MCH-02 3
        DB3 HO-MCH-03 3

        the fisrt one DB1 prefernce colored with green and the others DB2 & DB3 colored with yellow, could you please explain what this colores mean?

  22. Andrew says

    Hi,

    Great script thanks Paul :) I have setup scheduled tasks on your other ones and they send fine to multiple people, but with the DAG health one it seems to only send to the first person in the list. Is there need to do something slightly differenet with this script?

    Cheers

  23. says

    Version 1.1 of Get-DAGHealth.ps1 is now available for download via the link in the article above.

    Thanks to those who have provided bug reports and feedback so far. I appreciate your help making this script accurate and useful.

  24. Gilberth says

    Hello Paul this is a great script I have only one question, how I can have the report sent by email when autentication is required ?

  25. Julien says

    Very great job and wonderful script !

    Few questions :
    - When I do a detailed report, all the cells in the DAG Member Health array (last array) are yellow and there is “Transmis” inside. What does it mean ? (I’m on Exchange 2013 with CU1)
    - Do you plan to make Test-ExchangeServerHealth.ps1 & Get-DailyBackupAlerts.ps1 Exchange 2013 compatible ? (It would be great :-)

    • says

      The first problem sounds like a non-English language server. I have an idea how to make that easier to deal with but for now you’d need to just look at the HTML generating sections of the script and possibly replace English words like “Success” and “Passed” to your language’s word.

      Yes, I plan to test and update all the scripts for Exchange 2013 as time permits.

  26. Brian says

    Hi Paul,

    Thanks for the script and Awesome work, challenge is when i execute is doens’t generate all the output on the email and i get the following errors on the Shell window;
    “You must provide a value for this property.
    + CategoryInfo : NotSpecified: (0:Int32) [Get-MailboxDatabase], DataValidationException
    + FullyQualifiedErrorId : 16C4924A,Microsoft.Exchange.Management.SystemConfigurationTasks.GetMailboxDatabase”

    This two sections are not populated on the email;
    “Database Availability Group SVDTDAG01 Health Summary:
    Database Mounted on Preference Total Copies Healthy Copies Unhealthy Copies Healthy Queues Unhealthy Queues Lagged Queues Healthy Indexes Unhealthy Indexes
    Database Availability Group SVDTDAG01 Health Details:
    Database Copy Database Name Mailbox Server Activation Preference Status Copy Queue Replay Queue Replay Lagged Truncation Lagged Content Index
    Database Availability Group SVDTDAG01 Member Health:”

    Kind Regards,
    Brian

  27. Stephen says

    I am having an issue with the scheduled task when i run it nothing happens but if I run the script manually with the options I get the email. For the arguments this is what i have:
    -command “c:\scripts\daghealth\get-daghealth.ps1 -Detailed -SendEmail”.
    Am i doing something wrong

      • Stephen says

        Ok i was trying to run it with a service account that has the password set to not expire but cannot log on locally to the server. It works with my domain admin account so I guess I will have to change the password on the task every month

        • says

          It doesn’t need to be a domain admin account. I’ll try and write up the specific RBAC roles the account needs to run this script without giving it too many rights.

        • Stephen says

          Ok will appreciate that. I tried running it with the local administrator account but it runs for several minutes without any output

        • says

          Local accounts certainly won’t work, it does need to be a domain account. From memory it needs at least Exchange View-Only Org rights (there’s an existing group for that) and I think I also needed it to be a member of the local administrators group on the management server I run it on, presumably due to some PowerShell requirement that I haven’t quite worked out.

  28. Skye says

    There is a bug in the script :

    Once the UPTIME counter reaches 1000+ hours, it shows ’1′ in the HTML output.

    We only just noticed this, because of monthly security updates force reboots often, except recently.

  29. Skye says

    Great script, I do get a warning when running it , but the output seems fine on first glance;

    WARNING: Unable to get Primary Active Manager information due to an Active
    Manager call failure. Error: An Active Manager operation failed. Error
    Operation failed with message: Error 0x6d1 (The procedure number is out of
    range) from cli_AmGetDeferredRecoveryEntries.

  30. Skye says

    I have a proposal for a new feature / improvement;

    We have hundereds of databases, so the output spans several screens. This prevents us from easily spotting problems a a glance on a monitoring screen.

    Would be great to have a switch (say -failureonly) that lists only the ‘failures’ in the output from;

    Database Availability Group Health Details
    Database Availability Group Health Summary

    cheers

  31. Chris says

    Hi,
    Thanks for writing this script. I have run the script and it sends me an e-mail but there is no data (blank). Any ideas why? I also get the errors described above after running. Thanks.

      • Chris says

        This is the error…sorry about that.

        Update-TypeData : The following error occurred while loading the extended type data file:
        Microsoft.PowerShell, D:\Program Files\Microsoft\Exchange Server\V14\bin\exchange.types.ps1xml : File skipped because it was already present from “Microsoft.PowerShell”.
        At D:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.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 Files\Microsoft\Exchange Server\V14\bin\Exchange.partial.Types.ps1xml : File skipped b
        ecause it was already present from "Microsoft.PowerShell".
        Microsoft.PowerShell, D:\Program Files\Microsoft\Exchange Server\V14\bin\exchange.types.ps1xml : File skipped because it was already present from "Microsoft.PowerShell".
        At D:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:104 char:16
        + Update-TypeData <<<< -PrependPath $partialTypeFile
        + CategoryInfo : InvalidOperation: (:) [Update-TypeData], RuntimeException
        + FullyQualifiedErrorId : TypesXmlUpdateException,Microsoft.PowerShell.Commands.UpdateTypeDataCommand

        • says

          You can just ignore those, they aren’t harmful to the running of the script.

          If you’re not getting any results try running the script with the -Verbose parameter and look through the output it produces.

  32. Jan says

    Hi,

    cool script… One suggestion – what you also could check is percentage of free space on the repsective DB/log disks and drop a warning if it goes below some threshold. Last successfult backup date could also be useful.

    keep up the good work
    Jan

  33. Julian Stephan says

    Paul,

    Is there a way to integrate if a DB is mounted on act. preference 2 to show which server it needs to be mounted on for act preference 1?

    Thank you,
    Julian

  34. Matt says

    Hey Paul,

    Does this work ok on 2013 CU1?

    We are doing a test migration from 2010 to 2013. I have created a new DB on the 2013 infrastructure and added it to a new 2013 DAG. In EAC, is is definately showing as healthy on both MBX servers and both servers are listed under ‘Servers with copies’, but when running the Get-DagHealth, it is reporting:

    VERBOSE: Retrieving Database Availability Groups
    VERBOSE: 1 DAGs found
    VERBOSE: —- Processing DAG DAGPREP1
    VERBOSE: 2 DAG members found
    VERBOSE: 0 DAG databases found

    • says

      What happens when you run this command? (use your DAG name instead of mine of course)

      Get-MailboxDatabase -Status | Where-Object {$_.MasterServerOrAvailabilityGroup -eq “E15DAG”}

      • Matt says

        Hey Paul,

        It returns the database OK:

        Get-MailboxDatabase -Status | Where-Object {$_.MasterServerOrAvailabilityGroup -eq “DAGPREP1″}

        Name Server Recovery ReplicationType
        —- —— ——– —————
        DB-2013-1 EX2013-MBX2 False Remote

        • Matt says

          No worries Paul, thank you.

          Can you see my email address that I have entered when posting these comments?

          If so, feel free to email me directly if you want some information regarding the configuration to assist. It is pretty much a stock standard install, in coexistence with exchange 2010, a new database created on the 2013 MBX server and added into the new DAG that was created on the 2013 infrastructure.

        • Matt says

          Doh! I didn’t even think to try from the 2013 server.

          I have just moved the script to a 2013 CAS server and it ran fine – fully reports on the DAG and the database in the DAG. Thanks for that. #FlipDeskFriday

  35. Julian Stephan says

    Hi Paul,

    Is there a way that we can run this report on multiple DAGs but possibly add an ignore line referencing a text file to not run on certain DAGs. We currently have 10 DAGs in our 2013 environment, but only 2 are in production so far with users.

    • says

      Look for the line in the script where Get-DatabaseAvailabilityGroup is run and modify that so it includes/excludes the DAGs you want. I’ll look at incorporating an “ignore” list into a future update.

  36. StatikD says

    Paul,

    Don’t know how tough it would be to add, but I’m supporting a large enterprise environment, and I was wondering if a status indicator, or progress of the script could be added. I’ve been running the script for about 35-40 minutes….

    Of course, once I get an idea of how long this script would actually take to run, it might not be necessary, but for testing purposes, it would be a good indicator.

    Just a thought.

    Thanks!

    Jeff

  37. Bill Keran says

    Feature Request and Question.
    Any Change of getting DB size included in this report?
    And, can the report be emailed as an attachment vs. embeded in the email?

    Thanks!

    I think this is THE best script I have found!

  38. Simon Craner says

    Hi All,
    I am trying to run this in my environment, trick is we shared an org with anotehr company.
    we have our own dag, with trying to edit the script to only target my dag, i dont get full details under Health Summary or Health Details, all under member health is fine.

    Any ideas?

    • Simon Craner says

      got it to work, it still scans other servers in the org, but report is only my stuff, say yay.
      once again, thanks Paul for a great script. Going to use this as a daily task now.

  39. JackSeth says

    Hi Chris, Great script. I am getting an error. I am not getting output on the Health Summary and Health Details. I do get output on the Server Test-Replication Report

    You must provide a value for this property.
    + CategoryInfo : NotSpecified: (0:Int32) [Get-MailboxDatabase], DataValidationException
    + FullyQualifiedErrorId : CEA6502,Microsoft.Exchange.Management.SystemConfigurationTasks.GetMailboxDatabase
    + PSComputerName : sj2-exca101.corp.ourdomain.com

  40. GC says

    I don’t want to create a distribution group for 2 recipients… Has anyone been able to define multiple recipients on the To = line? Using “firstemailaddress”,”secondemaladdress” only sends to the second one specified…

  41. mhd says

    Hi
    my dag seems healthy
    all mailboxdatabasescopysatus are healthy or mounted
    tet-replication health show everything passed
    but when i run this script it does not show me the passed status for mailbxo2
    i mean in the last table which it says about member health, mailbox2 cells are blank or n/a

    also when i run the script first it syas

    Windows Failover Clustering encountered a transient error. Trying the operation again may be successful. Error: ‘IsNodeClustered’.

    + CategoryInfo : NotSpecified: (0:Int32) [Test-ReplicationHealth], ExClusTransientException
    + FullyQualifiedErrorId : 2A256D90,Microsoft.Exchange.Monitoring.TestReplicationHealth

    Add-Member : Cannot bind argument to parameter ‘Name’ because it is null.
    At C:\Users\mganjida\Desktop\Mailbox Scripts Ganji\Get-DAGHealth.ps1:289 char:47
    + $memberObj | Add-Member NoteProperty -Name <<<< $($healthitem.Check) -Value $($healthitem.Result)
    + CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCommand

    and then it goes to end and completed
    can you please help me on this

  42. Andi says

    Is there a version with a parameter called DAGName ? We have about 12 DAG´s in the organization and i only need the health report from one of them…

      • Andi says

        Thanks for your fast reply !

        Does the Get-DAGHealth.ps1 script use the ignorelist.txt automatically when it is in the same folder ?
        Whats the syntax inside the ignorelist.txt ?

        • says

          Sorry, my bad, I thought we were talking about the Test-ExchangeServerHealth.ps1 script that this DAG health check was rolled into a while ago.

          To be honest this Get-DAGHealth.ps1 script is lagging behind a bit on bug fixes and feature improvements, but it still works for most people.

          So in your case I’d just recommend modifying line 103

          $dags = @(Get-DatabaseAvailabilityGroup -Status)

          …so that it only grabs the DAG you’re interested in, eg

          $dags = @(Get-DatabaseAvailabilityGroup -Status YOURDAGNAME)

  43. Vincent says

    Hello,

    Thanks for this script, look like very nice.

    Can i execute this script just for a specific DAG ?

    Cause i have many dag in my organisation with Domain contoller not open.
    So i have a lot of error.

    Thanks a lot for feedback

  44. Cobus Faasen says

    Hi all, the script runs fine and I get an output in HTML. However it is not showing the activation preference for databases on one server at all.

    If I run the Get-MailboxDatabase | select name,activationpreference command it show the activation preference as 5 which is correct.

    However on the reports the field is just blank and does not show a value of 5

  45. Cobus Faasen says

    Hi, please see output for the Get-MailboxDatabase | select name,activationpreference command

    Name : 1024-Normal Users (A-F)
    ActivationPreference : {[xxxxxx, 1], [xxxxxx, 2], [xxxxxx, 3], [xxxxxx, 4], [xxxxxx, 5]}

    Name : 1024-Normal Users (G-L)
    ActivationPreference : {[xxxxxx, 1], [xxxxxx, 2], [xxxxxx, 3], [xxxxxx, 4], [xxxxxx, 5]}

    Name : 1024-Generic Users
    ActivationPreference : {[xxxxxx, 1], [xxxxxx, 2], [xxxxxx, 3], [xxxxxx, 4], [xxxxxx, 5]}

    Name : 1024-VIP Users
    ActivationPreference : {[xxxxxx, 1], [xxxxxx, 2], [xxxxxx, 3], [xxxxxx, 4], [xxxxxx, 5]}

    Name : 1024-Normal Users (R-Z)
    ActivationPreference : {[xxxxxx, 1], [xxxxxx, 2], [xxxxxx, 3], [xxxxxx, 4], [xxxxxx, 5]}

    Name : 1024-Normal Users (M-Q)
    ActivationPreference : {[xxxxxx, 1], [xxxxxx, 2], [xxxxxx, 3], [xxxxxx, 4], [xxxxxx, 5]}

  46. Robert Eriksson says

    Hi

    Great script!!
    However I updated my servers to SP1 and now it doesn’t report like before.
    Preference is blank under “Database Availability Group DAG-SPL-01 Health Summary”. Activation Preference is blank under “Database Availability Group DAG-SPL-01 Health Details”. and not server names under “Database Availability Group DAG-SPL-01 Member Health”
    Known issue?

    Best regards
    Robert

  47. Jason says

    while trying to run your script i realized it is going to try and pull all DAGS in my forest which for my group that is around 50 or so of them, i only care about the ones i control, is there anyway to tell this script to look at one specific DAG or a group of dags that have the same general name?

    • says

      Modify the script line where it fetches the DAGs (using Get-DatabaseAvailabilityGroup).

      Or run Test-ExchangeServerHealth.ps1 instead which has an ignorelist.txt file you can use to exclude servers, databases, or DAGs.

  48. Barry Sherman says

    I am using the script and it works until I get to the send email switch. I am running the command as follows: .\Get-DAGHealth.ps1 -Detailed -SendEmail

    When it gets to the sending email part I get the following error:
    Send-MailMessage : Service not available, closing transmission channel. The server response was: 4.3.2 Service not active

    Any ideas?? Otherwise, an AWESOME script!!

  49. Hector Alvarez says

    Great script!
    Very useful, I use it to monitor a DAG that expands across 3 sites.
    I do have a quick question. I noticed that the script reports that one of the Exchange servers “DB Log replay keeping up” Failed.
    Now, I have setup database copies to that server to be lagged by 12 hours and I’m wondering if that is the reason for the “Failed” report or if it is an issue I need to look into it.
    Thank you

  50. Ben Stephenson says

    Great Script thank-you Paul!!!!

    Just wanted to quickly share, I had the same issue a few had that on a SP1 and above 2010 Exchange server the database preference column had stopped working. To fix I needed to change the $mailboxserver attribute to return a title-case value rather than upper case as this is the format the “ActivationPreference” section now returned.

    Here was my hack to fix (not a script-guy so may be better ways to do it sorry):

    changed:

    $mailboxserver = $dbcopy.MailboxServer
    Write-Verbose “Server: $mailboxserver”

    to:

    $mailboxserverupper = $dbcopy.MailboxServer
    $TextInfo = (Get-Culture).TextInfo
    $mailboxserver = $TextInfo.ToTitleCase($mailboxserverupper.ToLower())
    Write-Verbose “Server: $mailboxserver”

    All working properly now, thanks again for your hard work!

    Cheers
    Ben

  51. kwaks says

    Hi,
    is this download no longer available?
    I’m logged in, but unfortunately I’m not able to download this script. There is now download button or sth. else…

  52. Yogesh says

    Hi Paul,

    This is just great..
    I have two DAG in my exchange but I want a summary report of only one DAG.
    How can I do that? Can You guide me to changes required? I am a powershell beginner.

      • Yogesh says

        That’s Great.

        Still it tries to connect to other DAG Servers and displays error as ” unable to connect to Information Store service on Server1.*****.com”.

  53. Yogesh says

    Very Often I see the reports show “File Share Quorum” as “*FAILED*

    Is it something that It can not fetch into report?
    But then I manually run it after sometime and get all as passed.

  54. jtsai says

    I’m getting all the info except for server column on the last section for test-replication… any idea? lastest Exchange 2010 SP & Rollup.

  55. Tuan Bui says

    Hi Paul
    I running Scipt on Coexist exchange 2010 and exchange 2013.
    I had 2 DAG (1 For Exchange 2010 and 1 Exchange 2013). Exchange 2010 was OK, but Exchange 2013 not Run
    It not get healthy DAG exchange 2013 with 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.
    + CategoryInfo : NotSpecified: (:) [Get-DatabaseAvailabilityGroup], FileNotFoundException
    + FullyQualifiedErrorId : [Server=XXX2013,RequestId=faca3730-5443-4548-90e8-bddf46d82352,TimeStamp=10/27/2014 11:48:46 AM] [FailureCategory=Cmdlet-F
    ileNotFoundException] AF360ECA,Microsoft.Exchange.Management.SystemConfigurationTasks.GetDatabaseAvailabilityGroup
    + PSComputerName : XXX2013.domain.com

    Please can You help me fix it?

  56. Marcel says

    Hi,

    Today we’ve updated Exchange 2013 with CU6.
    If i run the script i get Cluster Network “*FAILED*”.
    The verbose output:
    [PS] C:\Program Files\Microsoft\Exchange Server\V15\Scripts>C:\Get-DAGHealth.ps1 -Detailed -SendEmail -Verbose -Debug
    VERBOSE: Retrieving Database Availability Groups
    VERBOSE: 1 DAGs found
    VERBOSE: —- Processing DAG DAG01
    VERBOSE: 2 DAG members found
    VERBOSE: 3 DAG databases found
    VERBOSE: —- Processing database DB01
    VERBOSE: DB01 has 2 copies
    VERBOSE: Database Copy: DB01\SCL-RJE-ML-0001
    VERBOSE: Server: SCL-RJE-ML-0001
    VERBOSE: Activation Preference: 1
    VERBOSE: Status: Mounted
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 0
    VERBOSE: Content Index: Healthy
    VERBOSE: Replay lag is False
    VERBOSE: Truncation lag is False
    VERBOSE: Database Copy: DB01\SCL-RJE-ML-0002
    VERBOSE: Server: SCL-RJE-ML-0002
    VERBOSE: Activation Preference: 2
    VERBOSE: Status: Healthy
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 0
    VERBOSE: Content Index: Healthy
    VERBOSE: Replay lag is False
    VERBOSE: Truncation lag is False
    VERBOSE: —- Processing database DB02
    VERBOSE: DB02 has 2 copies
    VERBOSE: Database Copy: DB02\SCL-RJE-ML-0002
    VERBOSE: Server: SCL-RJE-ML-0002
    VERBOSE: Activation Preference: 1
    VERBOSE: Status: Mounted
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 0
    VERBOSE: Content Index: Healthy
    VERBOSE: Replay lag is False
    VERBOSE: Truncation lag is False
    VERBOSE: Database Copy: DB02\SCL-RJE-ML-0001
    VERBOSE: Server: SCL-RJE-ML-0001
    VERBOSE: Activation Preference: 2
    VERBOSE: Status: Healthy
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 0
    VERBOSE: Content Index: Healthy
    VERBOSE: Replay lag is False
    VERBOSE: Truncation lag is False
    VERBOSE: —- Processing database SPAM
    VERBOSE: SPAM has 2 copies
    VERBOSE: Database Copy: SPAM\SCL-RJE-ML-0001
    VERBOSE: Server: SCL-RJE-ML-0001
    VERBOSE: Activation Preference: 1
    VERBOSE: Status: Mounted
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 0
    VERBOSE: Content Index: Healthy
    VERBOSE: Replay lag is False
    VERBOSE: Truncation lag is False
    VERBOSE: Database Copy: SPAM\SCL-RJE-ML-0002
    VERBOSE: Server: SCL-RJE-ML-0002
    VERBOSE: Activation Preference: 2
    VERBOSE: Status: Healthy
    VERBOSE: Copy Queue: 0
    VERBOSE: Replay Queue: 0
    VERBOSE: Content Index: Healthy
    VERBOSE: Replay lag is False
    VERBOSE: Truncation lag is False
    VERBOSE: —- Checking replication health for SCL-RJE-ML-0001
    VERBOSE: ClusterService Passed
    VERBOSE: ReplayService Passed
    VERBOSE: ActiveManager Passed
    VERBOSE: TasksRpcListener Passed
    VERBOSE: TcpListener Passed
    VERBOSE: ServerLocatorService Passed
    VERBOSE: DagMembersUp Passed
    VERBOSE: MonitoringService Passed
    VERBOSE: ClusterNetwork *FAILED*
    VERBOSE: QuorumGroup Passed
    VERBOSE: FileShareQuorum Passed
    VERBOSE: DatabaseRedundancy Passed
    VERBOSE: DatabaseAvailability Passed
    VERBOSE: DBCopySuspended Passed
    VERBOSE: DBCopyFailed Passed
    VERBOSE: DBInitializing Passed
    VERBOSE: DBDisconnected Passed
    VERBOSE: DBLogCopyKeepingUp Passed
    VERBOSE: DBLogReplayKeepingUp Passed
    VERBOSE: —- Checking replication health for SCL-RJE-ML-0002
    VERBOSE: ClusterService Passed
    VERBOSE: ReplayService Passed
    VERBOSE: ActiveManager Passed
    VERBOSE: TasksRpcListener Passed
    VERBOSE: TcpListener Passed
    VERBOSE: ServerLocatorService Passed
    VERBOSE: DagMembersUp Passed
    VERBOSE: MonitoringService Passed
    VERBOSE: ClusterNetwork *FAILED*
    VERBOSE: QuorumGroup Passed
    VERBOSE: FileShareQuorum Passed
    VERBOSE: DatabaseRedundancy Passed
    VERBOSE: DatabaseAvailability Passed
    VERBOSE: DBCopySuspended Passed
    VERBOSE: DBCopyFailed Passed
    VERBOSE: DBInitializing Passed
    VERBOSE: DBDisconnected Passed
    VERBOSE: DBLogCopyKeepingUp Passed
    VERBOSE: DBLogReplayKeepingUp Passed
    —- Database Copy Health Summary —-

    Database Mounted on Preference Total Copie Healthy Cop Unhealthy C Healthy Que Unhealthy Q Lagged Queu Healthy Ind
    s ies opies ues ueues es exes
    ——– ———- ———- ———– ———– ———– ———– ———– ———– ———–
    DB01 SCL-RJE-… 1 2 2 0 2 0 0 2
    DB02 SCL-RJE-… 1 2 2 0 2 0 0 2
    SPAM SCL-RJE-… 1 2 2 0 2 0 0 2

    —- Database Copy Health Details —-

    Database Na Database Co Mailbox Ser Activation Status Copy Queue Replay Queu Replay Lagg Truncation Content Ind
    me py ver Preference e ed Lagged ex
    ———– ———– ———– ———– —— ———- ———– ———– ———– ———–
    DB01 DB01\SCL… SCL-RJE-… 1 Mounted 0 0 False False Healthy
    DB01 DB01\SCL… SCL-RJE-… 2 Healthy 0 0 False False Healthy
    DB02 DB02\SCL… SCL-RJE-… 1 Mounted 0 0 False False Healthy
    DB02 DB02\SCL… SCL-RJE-… 2 Healthy 0 0 False False Healthy
    SPAM SPAM\SCL… SCL-RJE-… 1 Mounted 0 0 False False Healthy
    SPAM SPAM\SCL… SCL-RJE-… 2 Healthy 0 0 False False Healthy

    —- Server Test-Replication Report —-

    Server ClusterServ ReplayServi ActiveManag TasksRpcLis TcpListener ServerLocat DagMembersU MonitoringS ClusterNetw
    ice ce er tener orService p ervice ork
    —— ———– ———– ———– ———– ———– ———– ———– ———– ———–
    SCL-RJE-… Passed Passed Passed Passed Passed Passed Passed Passed *FAILED*
    SCL-RJE-… Passed Passed Passed Passed Passed Passed Passed Passed *FAILED*

    Do you have any idea why this reports failed?

    Thanks in advance,

    Marcel

    • says

      Run Test-Replication health and look at the details there. You might need to do “test-replicationhealth | fl” to see more info.

      If there’s no help there look in the event logs for more clues.

      The script is just reporting what it sees, it can’t troubleshoot for you.

      • Marcel says

        Hi Paul,

        Thanks for your quick reply!
        I’ve been able to fix the “misconfigured” issue it had to do with IPv6.
        All is ok now and I can confirm that both this and the Exchange Server Health Check Report work fine with CU6.

        Have a nice weekend.

        Marcel

Leave a Reply

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