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

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.