How Can I Get a List of All the Domain Controllers in My Domain?

Hey, Scripting Guy! Question

Hey, Scripting Guy! Is it possible to get a list of all the domain controllers in my domain?

— KT

SpacerHey, Scripting Guy! AnswerScript Center

Hey, KT. As a matter of fact, there are at least two ways to get a list of all domain controllers in your domain. The first way is pretty easy, but not guaranteed; depending on how you’ve set up Active Directory, you could miss a few of your domain controllers. The second way is a little bit more complicated, but barring any unforeseen circumstances, should always return a list of all your domain controllers.


Let’s take a look at the easy way first. By default, the Active Directory computer account for a domain controller is stored in the Domain Controllers OU. If that’s where all your domain controllers accounts are stored, then you can retrieve your list just by enumerating the computer accounts in that OU:

Set objOU = GetObject(“LDAP://ou=Domain Controllers, dc=fabrikam, dc=com”)
objOU.Filter = Array(“Computer”)
For Each objComputer in objOU
Wscript.Echo objComputer.CN
Next

The preceding script binds to the Domain Controllers OU and applies a filter to ensure that only computer accounts are returned. A simple For Each loop then walks us through the collection of returned computer accounts, echoing the CN (Common Name) for each one.


So what’s wrong with this script? Well, maybe nothing. However, it’s possible that you have domain controller accounts located elsewhere in Active Directory; if so, this script won’t do you much good. Likewise, it’s possible that you might have other computer accounts (such as those for member servers) in the Domain Controllers; if so, this script will mistakenly identify those computers as domain controllers. That’s because the script is just looking for computer accounts, period.


So what’s a more sure-fire way to get a list of all your domain controllers? Well, if you’re a regular reader of Hey, Scripting Guy! then you probably already guessed the answer: search Active Directory.


We know, sometimes it sounds like “Search Active Directory” is our standard response to any question. But, hey, Active Directory is a veritable storehouse of information, and it only makes sense to tap into that storehouse any chance you get. You want a list of all the domain controllers in a domain? Then run this script:

On Error Resume Next

Const ADS_SCOPE_SUBTREE = 2

Set objRootDSE = GetObject(“LDAP://RootDSE”)
strConfigurationNC = objRootDSE.Get(“configurationNamingContext”)

Set objConnection = CreateObject(“ADODB.Connection”)
Set objCommand = CreateObject(“ADODB.Command”)
objConnection.Provider = “ADsDSOObject”
objConnection.Open “Active Directory Provider”
Set objCommand.ActiveConnection = objConnection

objCommand.Properties(“Page Size”) = 1000
objCommand.Properties(“Searchscope”) = ADS_SCOPE_SUBTREE

objCommand.CommandText = _
“SELECT ADsPath FROM ‘LDAP://” & strConfigurationNC & “‘ WHERE objectClass=’nTDSDSA'”
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst
Do Until objRecordSet.EOF
Set objParent = GetObject(GetObject(objRecordset.Fields(“ADsPath”)).Parent)
WScript.Echo objParent.CN
objRecordSet.MoveNext
Loop


Ok, so it is a little more complicated, but it works and it will find all the domain controllers regardless of the location of their Active Directory accounts. The script starts out by binding to RootDSE and then connecting to the configuration naming context for the domain. (The configuration naming context – or configuration directory partition – holds information of global interest; for example, you’ll find things like the default configuration and policy information for all instances of a given service in the forest.)


From there we do a typical Active Directory search: we want to get the ADsPath for all nTDSDSA objects in the configuration naming context. For our purposes, nTDSDSA is short (in a roundabout way) for Directory System Agent, the software responsible – among other things – for providing access to the directory service. Which, of course, is exactly what a domain controller does.


Note, however, that a list of all the nTDSDSA objects is not the same thing as a list of all our domain controllers. The ADsPath to an nTDSDSA object tells us how to find that object in Active Directory; what it doesn’t tell us is the name of the computer that object is installed on (and if you have the nTDSDSA object installed, then you must be a domain controller). To determine the computer name, we have this crazy line of code:

Set objParent = GetObject(GetObject(objRecordset.Fields(“ADsPath”)).Parent)

What we’re doing here is first binding to an nTDSDSA object, and then immediately binding to that object’s Parent. In the case of the nTDSDSA object, the Parent object is the actual computer itself; in other words, binding to the nTDSDSA Parent binds us to the computer account (which, remember, has to be a domain controller, or it wouldn’t have the nTDSDSA object). At that point, we’ve finally reached a domain controller, and all we have to do then is echo back the CN for this computer. We then repeat the loop until we’ve handled all the nTDSDSA objects and – by extension – all the domain controllers in the domain.