Occasionally I'll run into a situation where a workstation hangs or fails when trying to retrieve information from Active Directory (AD).  In some cases the problem presents itself when running DSQUERY to query for Active Directory data.  In other cases it can a manifest itself as Exchange address book look up issue since the Global Address List for Exchange is stored in Active Directory and clients will connect to a Global Catalog (GC) server to perform look ups.

Active Directory uses the concept of sites to direct computers and users to local resources.  When a person authenticates to Active Directory they would typically be directed to a domain controller (DC) or GC witihn their site.  The same holds true when you query AD.   Client computers query DNS to find a local GC/DC within their site or the closest site.  I have seen cases where a client was directed to a GC within the same site but could not resolve the name because the GC was in a different domain and the client computer did not have the DNS search suffixes for domains configured.

The script below was developed to help isolate this type of issue.  The script will query AD for all GCs in the forest and then perform a query (domain admins group) against each one to confirm you can connect to the GC and query it.  The script will show output to the screen as well as write to a file named OUTPUT_GCLOOKUP.LOG.

The is one piece of "interesting" code in the script.  In an earlier version of the script I would query for a list of DCs then dump the list to a text file.  I would then use the file to as input for the script.  I recently updated the script so that I perform the query within the FOR loop and then loop through the result set.  In order to use the output from a command and then query the resulting output you must use the BACKQ switch and enclose the command in back quotes.  The back quote is also known as a Grave accent and is located on the same key as the tilde (~) character.  The original "text file" lines were left in the script and commented out so you can see the difference.

The Sample Output below indicates a problem.  The entries for DC3202 and DC2103 are blank and errors were displayed on the screen while the script was running indicating the client could not query the GCs.  Further investigation revealed these DCs were in a different domain and the names could not be resolved.  We discovered that the DNS search suffixes for the other domains were not configured therefore preventing proper name resolution.

Script Code

:::::::::::::::::::::::::::::::::::::   BEGIN SCRIPT CODE     ::::::::::::::::::::::::::::::::::::::::::::::::::::::

 @ECHO OFF
:: NAME: GCLOOKUP.CMD
:: DATE: 3:59 PM 8/17/2010
:: PURPOSE: Dump a list of all GCs in forest then perofrms a query against each one
::          to confirm connectivity
::
::

SET LOGFILENAME=OUTPUT_GCLOOKUP.LOG

:: Create List of GCs
REM dumps GCs to a txt file.
REM dsquery server -forest -o rdn -isgc > gc.txt - 

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

REM FOR /F "eol= tokens=1" %%i IN (GC.TXT) DO ( for queries using a txt file
REM replace line below with this one to use a file containing a list of GCs

FOR /F "usebackq eol= tokens=1" %%i IN (`dsquery server -forest -o rdn -isgc`) DO (
 ECHO ::::::::::::::::::::::::::::::::  %%i  :::::::::::::::::::::::::::::: >> %LOGFILENAME%
 ECHO.
 ECHO Testing GC %%i
 ECHO.
dsquery group -name "domain admins" -gc -s %%i
 dsquery group -name "domain admins" -gc -s %%i >> %LOGFILENAME% 
 ECHO. >> %LOGFILENAME%
 ECHO. >> %LOGFILENAME% 
)

GOTO EOF

:EOF

:::::::::::::::::::::::::::::::::::::   END SCRIPT CODE     ::::::::::::::::::::::::::::::::::::::::::::::::::::::

Sample Output

    DATE: Fri 01/28/2010
    TIME:  7:57:43.72
    USER: administrator
COMPUTER: UN1795
 COMMAND: GCLOOKUP.CMD  
  
 
::::::::::::::::::::::::::::::::  DC3202  ::::::::::::::::::::::::::::::  
    
::::::::::::::::::::::::::::::::  DC3304  :::::::::::::::::::::::::::::: 
"CN=Domain Admins,OU=Administrative Groups,DC=Contoso,DC=COM"
    
::::::::::::::::::::::::::::::::  DC1399  :::::::::::::::::::::::::::::: 
"CN=Domain Admins,OU=Administrative Groups,DC=Contoso,DC=COM"
    
::::::::::::::::::::::::::::::::  DC2103  ::::::::::::::::::::::::::::::  
    
::::::::::::::::::::::::::::::::  DC1033  :::::::::::::::::::::::::::::: 
"CN=Domain Admins,OU=Administrative Groups,DC=Contoso,DC=COM"