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.
‘TODO:
‘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.
Hi,
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.
Regards,
Marius
My bad. I didnt realize you just released it yesterday 🙂
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…
cheers,
Felipe
This version is bugged, I am about to release a new version.
cheers,
Felipe Ferreira
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!
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…
cheers,
Felipe
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.
‘TODO:
‘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
lineout=LCASE(objExecObject.StdOut.ReadLine())
‘Each line output is sent to parse function to check for keywords and update status
call parse(lineout)
loop
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
wscript.quit(intCritical)
else
msg1 = “OK – ”
wscript.echo msg1 & msg
wscript.quit(intOK)
end if
end function
function getname()
‘get NAME OF LOCAL PC
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%
loop
hostname=trim(hostname)
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
Hello,
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 🙂
Hey,
Sorry I have not tested in 64x bits. Maybe the comand line output is diffirent wich would cause problems.
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!
Hey T,
Sorry but I have not tested the script in 2008, will probably do so someitme in the future.
cheers,
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
I just want to know how to monitor AD replication and what services we can monitor through nagios for AD.
All,
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
Usage:
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
exec(cmd)
‘Generate NAGIOS compatible output from dcdiag
printout()
‘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
lineout=lcase(objExecObject.StdOut.ReadLine())
‘each line output is sent to parse function to check for keywords and update status
call parse(lineout)
loop
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”
next
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) & “. ”
next
‘What state are we in? Show and then quit with NAGIOS compatible exit code
if instr(msg,”CRITICAL”) then
wscript.echo “CRITICAL – ” & msg
wscript.quit(intCritical)
else
wscript.echo “OK – ” & msg
wscript.quit(intOK)
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”
‘Status
for loop1 = 0 to 6
status(loop1) = “CRITICAL”
next
‘Command to execute
cmd = “dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount”
else
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)
next
end if
next
end if
‘We end up with this to test:
pt “Command to run: ” & cmd
end function
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?
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!!
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.
Can we capture this by SNMP?
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
http://www.nsclient.org/nscp/ticket/602
Dennis,
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?
Hi,
I am using version 3.0-JJ-V0.3 that I found on
http://exchange.nagios.org/directory/Plugins/Operating-Systems/Windows/Active-Directory-%28AD%29-Check/details
Is this the latest version you were talking about ?
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))