Home > Nagios, plugins > nagios plugin to check active directory

nagios plugin to check active directory

March 23rd, 2009 Leave a comment Go to comments

Nagios plugin to check active directory, checkdc.vbs is a script that performs the checks done by dcdiag.exe and parse its output to a nagios format. Right now its a limited script, no arguments and wont allow to select what to check. It basicly runs this command:

dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount

So to have it installed, it does require the Windows Resource Kit tool command dcdiag.exe
witch you can download from here or from microsoft.com. Be sure to copy it to c:windowssystem32

It also requires Nagios nad  NRPE_NT agent, define the command/service in nagios server and deifne the nrpe.cfg.
For helping doing all these check this post

The script version 3.0 is available to download here.

NOTE: By default in Windows 2003 the TrkSvr which is the Distributed Link Tracking Server,  is set to disabled in also the TrkWrks  Distributed Link Tracking Server, causing the script to go to Critical .
Set those and RPCLocator services to automatic and started them the issue will be resolved.

More details:

‘Script to check the status of a DOMAIN controller and report to Nagios
‘requires DCDIAG.EXE
‘Author: Felipe Ferreira
‘Version: 3.0
‘For now just check all tests and report critical if one fails.
‘If need to check just specific tests edit cmd variable and remove all checks vars.
‘Get from args what to check, update status to 2 and also build the cmd line
‘loop thru args and with a select update tests status to 2

Fixed and Working.

  1. March 24th, 2009 at 12:07 | #1


    Have you managed to update the checkads script as your TODO notes? I am contemplating on using it to check the status of ADS on several windows servers. At present I am monitoring distinct services such as NTDS …. your script seems to help in this area.


  2. March 24th, 2009 at 12:08 | #2

    My bad. I didnt realize you just released it yesterday 🙂

  3. xoroz
    March 24th, 2009 at 12:19 | #3

    hey Marius,
    I am happy enough with its current functionality. I dont see the need to check just parts of the dcdiag tests, so untill then I wont do it. Although I do have a version of the script (version 2.0) that was aimed to that direction. I will leave the source http://www.xoroz.com/files/scripts/nagios/checkdc_beta.txt it takes multiple arguments…

  4. April 1st, 2009 at 11:58 | #4

    This version is bugged, I am about to release a new version.
    Felipe Ferreira

  5. July 6th, 2009 at 08:56 | #5

    I’m having a small problem with this script, it works but sometimes i get some report like this…

    SERVER02 – CheckDC – CRITICAL 07-06-2009 08:49:40 0d 0h 12m 42s 3/3 CRITICAL – Services: OK Replications: OK Advertising: CRITICAL Fsmocheck: Ridmanager: OK Machineaccount: OK

    Shows everything with OK, but it report like critical.

    why is this?

    Thanks for your great work!

    • admin
      July 7th, 2009 at 15:01 | #6

      Hi Vdias,
      Try executing directly from the server cmd prompt: dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount
      These report all as OK? Also if edit the script you can remove some of the tests…

  6. Diego Fernández
    March 25th, 2010 at 06:28 | #7

    Para la versión en español del dcdiag. For the spanish version of dcdiag.

    he añadido un left para la cadena de comparación porque me añade al final un caracter de retorno de carro que no se como quitar, siento la ñapa. Pero funciona.

    ‘Script to check the status of a DOMAIN controller and report to Nagios
    ‘requires DCDIAG.EXE
    ‘Author: Felipe Ferreira
    ‘Version: 3.0

    ‘For now just check all tests and report critical if one fails.
    ‘If need to check just specific tests edit cmd variable and remove all checks vars.

    ‘Get from args what to check, update status to 2 and also build the cmd line
    ‘loop thru args and with a select update tests status to 2

    Dim verbose : verbose = 0
    ‘———-NAGIOS VARs
    Const intOK = 0
    Const intWarning = 1
    Const intCritical = 2
    Const intError = 3
    Dim cmd
    Dim hostname
    ‘State of Checks ( OK, or CRITICAL)
    Dim services : services = “CRITICAL”
    Dim replications : replications = “CRITICAL”
    Dim advertising : advertising = “CRITICAL”
    Dim fsmocheck : smocheck = “CRITICAL”
    Dim ridmanager : ridmanager = “CRITICAL”
    Dim machineaccount : machineaccount = “CRITICAL”

    ‘@@@@@@@@@@ MAIN CALLS @@@@@@@@@@@@@@
    ‘CMD Options are: dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount
    cmd = “dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount”

    call getname()
    call exec(cmd)
    call printout()

    ‘@@@@@@@@@@ FUNCTIONS @@@@@@@@@@@@@@@
    function exec(strCmd)
    dim objShell : Set objShell = WScript.CreateObject(“WScript.Shell”)
    call pt( strCmd )
    Dim objExecObject,lineout
    Set objExecObject = objShell.Exec(strCmd)
    Do While Not objExecObject.StdOut.AtEndOfStream
    ‘Each line output is sent to parse function to check for keywords and update status
    call parse(lineout)
    if err.number = 0 and objExecObject.Status = 1 then
    call pt(“done”)
    elseif (err.number 0 ) then
    wscript.echo(“Error ” & err.Description & ” ” & Err.number)
    end if
    end function

    function parse(txtp)
    ‘Parse output of dcdiag command and change state of checks
    if instr(txtp,”super¢ la prueba”) then
    txtp = Replace(txtp,”.”,””)
    pt “PASSED ” & txtp
    txtp = Replace(txtp,”super¢ la prueba”,””)
    txtp = Replace(txtp,hostname,””)
    txtp = Replace(txtp,” “,””)
    txtp = Trim(txtp)
    txtp = Left (txtp,8)

    Select case txtp
    case “services”
    services = “OK”
    case “replicat”
    replications = “OK”
    case “advertis”
    advertising = “OK”
    case “fsmochec”
    fsmocheck = “OK”
    case “ridmanag”
    ridmanager = “OK”
    case “machinea”
    machineaccount = “OK”
    end select

    elseif instr(txtp,”no super¢ la prueba”) then
    txtp = Replace(txtp,”.”,””)
    pt “FAIL ” & txtp
    txtp = Replace(txtp,”no super¢ la prueba”,””)
    txtp = Replace(txtp,hostname,””)
    txtp = trim(txtp)
    txtp = Left (txtp,8)

    Select Case txtp
    case “services”
    services = “CRITICAL”
    case “replications”
    replicat = “CRITICAL”
    case “advertising”
    advertis = “CRITICAL”
    case “fsmocheck”
    fsmochec = “CRITICAL”
    case “ridmanager”
    ridmanag = “CRITICAL”
    case “machineaccount”
    machinea = “CRITICAL”
    end select

    end if
    end function

    function printout()
    ‘outputs result
    dim msg1,msg

    msg = “Services: ” & services & ” Replications: ” & replications & ” Advertising: ” & advertising & ” Fsmocheck: ” &_
    fsmocheck & ” Ridmanager: ” & ridmanager & ” Machineaccount: ” & machineaccount

    if instr(msg,”CRITICAL”) then
    msg1 = “CRITICAL – ”
    wscript.echo msg1 & msg
    msg1 = “OK – ”
    wscript.echo msg1 & msg
    end if

    end function

    function getname()
    dim objShell2 : Set objShell2 = WScript.CreateObject(“WScript.Shell”)
    Dim objExecObject2
    Set objExecObject2 = objShell2.Exec(“cmd /c hostname”)
    Do While Not objExecObject2.StdOut.AtEndOfStream
    hostname = LCASE(objExecObject2.StdOut.ReadLine()) ‘gets %userdomain%
    pt hostname
    end function

    Function help()
    wscript.echo “checkdc.vbs – Nagios NRPE Plugin for Active Directory Health Check” & vbcrlf & _
    “Version 3.0, By Felipe Ferreira http://www.felipeferreira.net” & vbcrlf & _
    “Usage:” & vbcrlf & _
    “checkdc.vbs ” & vbcrlf & _
    ” :services, replications, advertising, fsmocheck, ridmanager, machineaccount” & vbcrlf & vbcrlf & _
    “Checks domain controller functionality by using dcdiag tool from” & vbcrlf & _
    “Windows Support Tools. Following dcdiag tests are performed”

    end function

    Function pt(msgTxt)
    ‘Prints msg on screen only if Verbose is set
    if Verbose = 1 then
    wscript.echo msgTXT
    end if
    end Function

  7. Alibaskins
    April 2nd, 2010 at 10:23 | #8


    I have a problem with this script.
    On 2 Windows Server 2003 32bits it’s works. But on one windows server 2003 64bits all results are critical, but with the commande line all check are “passed test”.

    Have you test this script on 64 bits server ?

    Thks 🙂

    • April 5th, 2010 at 20:10 | #9

      Sorry I have not tested in 64x bits. Maybe the comand line output is diffirent wich would cause problems.

  8. July 13th, 2010 at 08:48 | #10

    I tried this script, but when I run it, I get an CRITICAL on all tests. If I run the dcdiag-Test manually, everything is fine.

    In the comment stands, that some service must be activated in windows 2003. But what is with windows 2008? And how is the name of the service, to start it via “net start”? I did not find anything.

    Thanks for your help!

    • July 14th, 2010 at 19:12 | #11

      Hey T,
      Sorry but I have not tested the script in 2008, will probably do so someitme in the future.

  9. Graham
    July 21st, 2010 at 11:58 | #12

    Seem to have vbCr at end of lines on win server 2008 r2 64-bit. Also needed to remove domain name rather than machine name from the output for the FsmoCheck

  10. chandra
    September 23rd, 2010 at 12:37 | #13

    I just want to know how to monitor AD replication and what services we can monitor through nagios for AD.

  11. November 16th, 2010 at 12:21 | #14

    Many thanks to Felipe for creating and publishing his script, I’ve made som minor changes.

    Feedback appreciated to email address embedded in the script. As my domain is not broken, its a bit difficult to test all elements. I dont monitor this thread, so dont expect any feedback from me here. For change request and bug fixes, email me.

    Changes: General fixup / optimization of code & added command line parameter support

    cscript Check_AD.vbs //nologo /test:connectivity,ridmanager
    cscript Check_AD.vbs //nologo
    cscript Check_AD.vbs /test:connectivity,ridmanager
    cscript Check_AD.vbs

    ‘Script to check the status of a DOMAIN controller and report to Nagios
    ‘requires DCDIAG.EXE
    ‘Author: Felipe Ferreira
    ‘Version: 3.0

    ‘Mauled over by John Jore, j-o-h-n-a-t-j-o-r-e-d-o-t-n-o 16/11/2010 to work on W2K8, x32
    ‘as well as remove some, eh… un-needed lines of code and general optimization as well as adding command parameter support
    ‘Tested by JJ on W2K8 SP2, x86
    ‘ W2K3 R2 SP2, x64
    ‘Todo: Proper error handling

    ‘Force all variables to be declared before usage
    option explicit

    ‘Array for name and status (Ugly, but redim only works on last dimension, and can’t set initial size if redim 🙁
    dim name(), status()
    redim preserve name(0)
    redim preserve status(0)

    ‘Debug switch
    dim verbose : verbose = 0

    ‘Return variables for NAGIOS
    const intOK = 0
    const intWarning = 1
    const intCritical = 2
    const intUnknown = 3

    ‘Call dcdiag and grab relevant output

    ‘Generate NAGIOS compatible output from dcdiag

    ‘call dcdiag and parse the output
    sub exec(strCmd)
    ‘Declare variables
    dim objShell : Set objShell = WScript.CreateObject(“WScript.Shell”)
    dim objExecObject, lineout

    ‘Command line options we’re using
    pt strCmd

    Set objExecObject = objShell.Exec(strCmd)
    ‘Loop until end of output from dcdiag
    do While not objExecObject.StdOut.AtEndOfStream
    ‘each line output is sent to parse function to check for keywords and update status
    call parse(lineout)
    end sub

    sub parse(txtp)
    ‘Parse output of dcdiag command and change state of checks
    dim loop1

    if instr(lcase(txtp), lcase(“passed test”)) then
    ‘What are we testing for now?
    pt txtp

    ‘What services are ok? ‘By using instr we don’t need to strip down text, remove vbCr, VbLf, or get the hostname
    for loop1 = 0 to Ubound(name)-1
    if (instr(lcase(txtp), lcase(name(loop1)))) then status(loop1)=”OK”
    end if

    ‘If default value at start of runtime is “CRITICAL”, there is no point in testing for it to set it again?
    end sub

    ‘outputs result for NAGIOS
    sub printout()
    dim loop1, msg : msg = “”

    for loop1 = 0 to ubound(name)-1
    msg = msg & name(loop1) & “: ” & status(loop1) & “. ”

    ‘What state are we in? Show and then quit with NAGIOS compatible exit code
    if instr(msg,”CRITICAL”) then
    wscript.echo “CRITICAL – ” & msg
    wscript.echo “OK – ” & msg
    end if
    end sub

    ‘Print messages to screen for debug purposes
    sub pt(msgTxt)
    if Verbose then
    wscript.echo msgTXT
    end if
    end sub

    ‘What tests do we run?
    function cmd()
    dim loop1, test, tests

    ‘If no command line parameters, then go with this default
    if Wscript.Arguments.Count = 0 Then
    redim preserve name(6)
    redim preserve status(6)

    ‘Test name
    name(0) = “services”
    name(1) = “replications”
    name(2) = “advertising”
    name(3) = “fsmocheck”
    name(4) = “ridmanager”
    name(5) = “machineaccount”

    for loop1 = 0 to 6
    status(loop1) = “CRITICAL”

    ‘Command to execute
    cmd = “dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount”
    cmd = “dcdiag” ‘Start with this
    for loop1 = 0 to wscript.arguments.count – 1
    if (instr(lcase(wscript.Arguments(loop1)), lcase(“/test”))) then
    ‘Strip down the test to individual items
    tests = right(wscript.arguments(loop1), len(wscript.arguments(loop1))-6)
    pt “Tests: ‘” & tests & “‘”

    tests = split(tests,”,”)
    for each test in tests
    cmd = cmd & ” /test:” & test

    ‘Expand the array
    redim preserve name(ubound(name)+1)
    redim preserve status(ubound(status)+1)

    ‘Store name of test and status
    name(Ubound(name)-1) = test
    status(Ubound(status)-1) = “CRITICAL” ‘Default status. Change to OK at runtime

    ‘pt “Contents: ” & name(Ubound(name)-1) & ” ” & status(Ubound(status)-1)
    end if
    end if

    ‘We end up with this to test:
    pt “Command to run: ” & cmd
    end function

  12. Diego Silva
    September 22nd, 2011 at 10:59 | #15

    Good morning,
    I can not work with Windows Server 2008 64bit
    If I run the commands
    dcdiag / test: services / test: replications / test: advertising / test: FsmoCheck / test: RidManager / test: MachineAccount –
    the test is performed successfully
    But with the script in all of Critical
    Can anyone help?

  13. Diego Silva
    September 22nd, 2011 at 12:43 | #16

    I did it! The problem was that the server was in Portuguese, with the return of dcdiag.exe it was in Portuguese and the script is in English.
    There is the hint!!

  14. Patrick
    October 12th, 2011 at 14:18 | #17

    The fix for the 2008 servers is to add a the following between these two lines:

    Find this:
    txtp = Replace(txtp,hostname,””)
    txtp = trim(txtp)

    Add this:
    txtp = Replace(txtp,chr(10),””)
    txtp = Replace(txtp,chr(13),””)

    This will strip out CR/LF characters that break the script.

  15. vsinha
    December 12th, 2011 at 11:39 | #18

    Can we capture this by SNMP?

  16. DennisPR
    November 14th, 2013 at 13:25 | #19

    Script works fine most of the time but sometimes exits with error code -1073741819
    Resulting in an unknown state for Nagios
    Anyone got any suggestions for this ?

    I don’t seem to be the only person running in to this problem

    • admin
      November 19th, 2013 at 16:37 | #20


      I have not updated the script in a while.
      It could be a problem when the dcdiag takes too long to execute and breaks.
      Someone updated the code for a win 2008 version, have u tried that?

  17. Name
    December 2nd, 2013 at 15:25 | #21

    I am using version 3.0-JJ-V0.3 that I found on
    Is this the latest version you were talking about ?

  18. ceooph
    November 13th, 2014 at 13:42 | #22

    To use on French server put this line between line 95 and 96. (Test on Windows 2008R2 French edition)

    elseif (instr(lcase(txtp), lcase(“Diagnostic du serveur d’annuaire”))) then ‘French
    pt “Detected French Language, changing the global test strings to look for”
    strOK = “r”&(Chr(130))&”ussi” ‘Chr(130) not equal é but it works !
    strNotOk = (Chr(130))&”chou”&(Chr(130))

  1. April 1st, 2009 at 07:05 | #1