Sunday, February 28, 2010

Automate DCDiag on your Domain Controllers

I’ve been doing this for (literally) years.  About 7 years to be exact.  You can do this with NETDIAG, REPADMIN and several other “diagnostic” utilities that work from the command line.

The idea is to wrap the diagnostic operation inside a script so that you can capture the output in a text file, then turn around and open the text file to parse it for what you want.  Then you can do almost anything with that information:

  • Generate a summary report file
  • Send the results into a database table
  • Send the results as an e-mail report
  • and on and on and on…

There are several ways to set this up as well.  For this example I’m using a VBScript file, a domain user (aka “service” or “proxy”) account, and the Windows Task Scheduler on a Windows Server 2008 domain controller.  This works just fine on Windows Server 2003 and Windows Server 2008 R2 as well.

The Script:

Const logFileName = "x:\logs\dcdiag.log"
Const ForReading = 1
Const ForWriting = 2

Dim objShell, objFSO, computer, domain, cmdstr
Dim objFile, testLabel, passed, failed

Set objShell = CreateObject("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")

computer = Ucase(objShell.ExpandEnvironmentStrings("%computername%"))
domain = Ucase(objShell.ExpandEnvironmentStrings("%userdnsdomain%"))

cmdstr = "cmd /c dcdiag /v >" & logFileName

objShell.Run cmdstr, 1, True

If objFSO.FileExists(logFileName) Then
passed = 0
failed = 0

Set objFile = objFSO.OpenTextFile(logFileName, ForReading)

Do Until objFile.AtEndOfStream
strLine = objFile.Readline

testLabel = Mid(strLine, 36)

If InStr(1, testLabel, computer & " passed test") > 0 Then
wscript.echo testLabel
passed = passed + 1
ElseIf InStr(1, testLabel, computer & " failed test") > 0 Then
wscript.echo testLabel
failed = failed + 1
ElseIf InStr(1, testLabel, domain & " passed test") > 0 Then
wscript.echo testLabel
passed = passed + 1
ElseIf InStr(1, testLabel, domain & " failed test") > 0 Then
wscript.echo testLabel
failed = failed + 1
End If
Set objFSO = Nothing

wscript.echo "Passed " & passed & " tests"
wscript.echo "Failed " & failed & " tests"
wscript.echo "fail: log file not found"
End If

Set objFSO = Nothing
Set objShell = Nothing

The Explanation:

The top section defines the path and filename for the output file we’re going to capture and analyze.  Next we define some variables.  Then we instantiate the Shell and FileSystemObject object interfaces. 

We use the Shell object to fetch the name of the computer and the domain name. We need those to help sift through the output file and find the matching lines we want to look at.  The Shell object is also used to run the DCDIAG command via the “Run” method.

After running the shell command, we then check if the output file exists.  If it does, we open it and read through it line-by-line looking for matching strings.  Within each matching string we look for “passed” or “failed” and count them up as well as echo them to the command prompt.

At the end we mop up and then display the tally for passed and failed tests.

Important Note: This is only ONE form of doing this.  There is no limit to what you CAN do.  For example, instead of echoing the testLabel contents, we could concatenate them into a report text block and send it via CDOsys (e-mail) or stuff it into a database via ADO or XML or generate an XML or HTML report, or even stuff it directly into a Microsoft Word or Excel document.  The possibilities are endless.

If anyone is interested in variations on this just post a comment and I’ll see what I can do.  I hope this helps someone out there?


  1. This Script is nearly what I am after, again I am in a simialr situation where I really want to automate DCDIAG, NETDIAG & REPADMIN, and with all this I am wanting to not have any interaction with the script running. Unfortunately I am still trying to get an understanding of creating my own scripts, hence the reason why I am posting to your blog.

    Really waht I would like for the script to do is to run the DCDIAG, NETDIAG & REPADMIN have the output got to a txt or log file and this then emailed to an specific account. Is this possible, probably a silly question, but I would be very keen on seeing a script for something like this.

    Thanks in advance.


  2. Thanks, um, "PDG", I appreciate that.

    Yes, you can make a script do almost anything. Stuff data into a database or a file, send an email, shutdown a computer (the one used by your irritating coworker), send emails from the CEO to his secretary (no, don't do that, just joking here), and order pizza (yep, can do). There's all sorts of ways to have scripts email output data. Shoot me an email at ds0934 (at) gmail (dot) com with some info about what you're trying to do and I'll try to help.