Finding All Domains in an Active Directory Forest
Using LDAP to explore an Active Directory Forest and Find All Member Domains

When connecting to an Active Directory domain, the server offers some information useful in exploring details of the entire forest. These details are contained in the rootDSE or root domain server entry. By default, this is the only information available without authenticating to the server. Some environments are configured to require authentication to even show this data so don't assume it will be available.

These attribute values of the rootDSE to be particularly valuable for exploring the forest:

  • The dnsHostname is the fully-qualified domain name of the server. This should be used to ensure future connections are to the same server.
  • The configurationNamingContext is a partition that is replicated to all domain controllers. Within this partition is a wealth of information about the forest as well as definitions of sites and partitions.
  • the defaultNamingContext defines the NCName of the domain to which the server belongs. The NCName can be used to bind to the domain partition or to search more information about the domain in the partitions container under the configurationNamingContext container.
  • The rootDomainNamingContext defines the NCName of the forest root. The NCName can be used to bind to the domain partition or to search more information about the domain in the partitions container under the configurationNamingContext container.
  • The isGlobalCatalogReady attribute is a Boolean indicates if you've connected to an active GC. A word to the wise: never assume the GC service is running. I have seen GCs go offline for indeterminate reasons and I use this flag to confirm.
Visual Basic .Net Sample - Reading the RootDSE

Dim Arr() As System.String

Dim req As New SearchRequest

Dim resp As SearchResponse

'Set the server name to empty string to use default domain controller.

Dim id As New LdapDirectoryIdentifier("", 389, False, False)

Dim ldap As New LdapConnection(id)

Dim entry As SearchResultEntry

Arr = New System.String() {"dnsHostName", "configurationNamingContext", _

"defaultNamingContext", "rootDomainNamingContext", "isGlobalCatalogReady", _

"dsServiceName"}

req.Attributes.AddRange(Arr)

req.Filter = "objectClass=*"

'An empty string is required to query the rootDSE.

req.DistinguishedName = ""

'An empty Must set scope to Base to query rootDSE.

req.Scope = SearchScope.Base

resp = ldap.SendRequest(req)

If resp.ResultCode = ResultCode.Success Then

entry = resp.Entries(0)

For Each strAttributeName As System.String In Arr

If entry.Attributes.Contains(strAttributeName) Then

'each attribute is returned as an array of values

Debug.Write (entry.Attributes(strAttributeName)(0))

End If

Next

End If