Obscurum per Obscurius

Explaining the obscure by means of the more obscure

How to run DCDIAG and NETDIAG on Multiple Computers Using a Batch File

How to run DCDIAG and NETDIAG on Multiple Computers Using a Batch File

  • Comments 7

I was onsite with a customer this week reviewing their Active Directory configuration.  During the visit the system admin I was working with mentioned he needed to run DCDIAG and NETDIAG on every domain controller (DC) in his domain and collect the output to prepare for their upcoming migration to Office 365.  When I got there he was logging into each via terminal services to collect the information.  I recognized these tasks as something we could automate with a simple batch file using a FOR loop so I suggested we spend a few minutes putting the scripts together.

DCDIAG

Running DCDIAG on a remote system is straightforward.  You just run “DCDIAG /s <server>” to test a remote server.  The next thing we needed was a list of all the domain controllers in his domain.  The forest had several domains.  Each domain was administered by a different IT group.  The following command line was used to generate the SERVERS.TXT file we will use to run the script:

DSQUERY SERVER -domain CONTOSO -O RDN >SERVERS.TXT

The following script (GET-DCDIAG.CMD) was used to run DCDIAG on all DCs contained in the SERVERS.TXT file and write to the log file (DCDIAG_OUTPUT.LOG). If you have looked at any of my previous script posts on this blog you will notice I use the same basic script and just modify  couple of lines for the task at hand.

:::::::::::::::::::::::::: BEGIN SCRIPT ::::::::::::::::::::::::::::::::

@ECHO OFF
:: NAME:GET-DCDIAG.CMD
:: DATE: 3/7/2013
:: PURPOSE:  Run DCDIAG on a list of servers
::
:: The SERVERS.TXT contains a list of servers (one server per line)
 
SET LOGFILENAME=DCDIAG_OUTPUT.LOG

ECHO     DATE: %DATE% > %LOGFILENAME%
ECHO     TIME: %TIME% >> %LOGFILENAME%
ECHO     USER: %USERNAME% >> %LOGFILENAME%
ECHO COMPUTER: %COMPUTERNAME% >> %LOGFILENAME%
ECHO. >> %LOGFILENAME%
ECHO. >> %LOGFILENAME%
ECHO. >> %LOGFILENAME%

FOR /F "tokens=1" %%i in (servers.txt) DO (
  ECHO ::::::::::::::::::::::  %%i  :::::::::::::::::::::::::: >> %LOGFILENAME%
  ECHO Running command on... %%i
  ECHO. >> %LOGFILENAME%
DCDIAG /s:%%i  >> %LOGFILENAME%
  ECHO. >> %LOGFILENAME%
  ECHO. >> %LOGFILENAME%
)

GOTO EOF

:EOF
ECHO.
ECHO.
ECHO  %0 COMPLETED!
ECHO.
ECHO.
ECHO.
:::::::::::::::::::::::::: END SCRIPT :::::::::::::::::::::::::::::::::::

 

NETDIAG

Collecting the NETDIAG information turned out to be more of a challenge.  The first issue we found is that NETDIAG is not supported on Windows Server 2008 and later operating systems and there is no replacement for NETDIAG.  Since most of the DCs were still running Windows Server 2003 this issue was not a show stopper.  The second issue was revealed we ran NETDIAG /? and noticed there was no switch to run the command on a remote server.  Hmmm…now what? 

I remembered a utility in the Sysinternals toolkit (http://technet.microsoft.com/en-us/sysinternals/default ) called PSEXEC that can be used to run commands on a remote system (http://technet.microsoft.com/en-us/sysinternals/bb897553).  We downloaded PSEXEC.EXE and copied the file to our local working directory.  Next we tested the functionality by running PSEXEC \\<server> Hostname  to confirm we had the correct command syntax to retrieve information from a remote computer.  We used the same script template shown above and created a GET-NETDIAG.CMD script to collect the information.  The code is shown below.  We changed the log file name and the a single command line.

:::::::::::::::::::::::::: BEGIN SCRIPT ::::::::::::::::::::::::::::::::

@ECHO OFF
:: NAME:GET-NETDIAG.CMD
:: DATE: 3/7/2013
:: PURPOSE:  Run NETDIAG on a list of servers
::
:: The SERVERS.TXT contains a list of servers (one server per line)
 
SET LOGFILENAME=NETDIAG_OUTPUT.LOG

ECHO     DATE: %DATE% > %LOGFILENAME%
ECHO     TIME: %TIME% >> %LOGFILENAME%
ECHO     USER: %USERNAME% >> %LOGFILENAME%
ECHO COMPUTER: %COMPUTERNAME% >> %LOGFILENAME%
ECHO. >> %LOGFILENAME%
ECHO. >> %LOGFILENAME%
ECHO. >> %LOGFILENAME%

FOR /F "tokens=1" %%i in (servers.txt) DO (
  ECHO ::::::::::::::::::::::  %%i  :::::::::::::::::::::::::: >> %LOGFILENAME%
ECHO Running command on... %%i
  ECHO. >> %LOGFILENAME%
PSEXEC -h \\%%i NETDIAG  >> %LOGFILENAME%
  ECHO. >> %LOGFILENAME%
  ECHO. >> %LOGFILENAME%
)

GOTO EOF

:EOF
ECHO.
ECHO.
ECHO  %0 COMPLETED!
ECHO.
ECHO.
ECHO.
:::::::::::::::::::::::::: END SCRIPT :::::::::::::::::::::::::::::::::::

 

So there you have it.  We spent about 10 minutes modifying one of my standard script templates to create two scripts that collected the information from multiple DCs in a few short minutes.  Please leave me a comment if you find this useful.

Leave a Comment
  • Please add 5 and 6 and type the answer here:
  • Post
  • This is wonderful however there is not dcdiag results. i checked the log and it says dcdiag completed but there is no dcdiag output. whether there was any error in dcdiag on any server.

  • @Himanshu - Are you using /Q switch on DCDIAG which suppresses everything that is not an error?

  • Works fine for me, just what I was after, thank you

  • how can we run batch file on multiple pc from a single pc without using remote desktop

  • @aditya, you can only run a batch file against remote machines if the command you are running supports running it remotely (e.g. DCDIAG).  You might look at using PowerShell native commands or PowerShell remoting to accomplish your work.

  • What if you are managing different domains? i mean, will this work to capture, let's say, 3 different domains dcdiag output (each of them has 3 DC's e.g.). 9 DC's. No trusts between them.

    Thanks!

  • @Curious  - If you have an administrator account in each domain with the same username/password it "might" work.  Worst case scenario just copy the script and binaries to a computer in each domain.

Page 1 of 1 (7 items)