Listing all domains in a forest
These snippets of code shows how to search Active Directory using LDAP to return all domains in the current Forest (based on current authentication).
For VB and C# a reference to System.DirectoryServices is required within the project.
C# .NET
// Connect to RootDSE
DirectoryEntry RootDSE = new DirectoryEntry("LDAP://rootDSE");
// Retrieve the Configuration Naming Context from RootDSE
string configNC =
RootDSE.Properties["configurationNamingContext"].Value.ToString();
// Connect to the Configuration Naming Context
DirectoryEntry configSearchRoot = new DirectoryEntry("LDAP://" + configNC);
// Search for all partitions where the NetBIOSName is set.
DirectorySearcher configSearch = new DirectorySearcher(configSearchRoot);
configSearch.Filter = ("(NETBIOSName=*)");
// Configure search to return dnsroot and ncname attributes
configSearch.PropertiesToLoad.Add("dnsroot");
configSearch.PropertiesToLoad.Add("ncname");
SearchResultCollection forestPartitionList = configSearch.FindAll();
// Loop through each returned domain in the result collection
foreach (SearchResult domainPartition in forestPartitionList)
{
// domainName like "domain.com". ncName like "DC=domain,DC=com"
string domainName = domainPartition.Properties["dnsroot"][0].ToString();
string ncName = domainPartition.Properties["ncname"][0].ToString();
}
PowerShell
# Connect to RootDSE
$rootDSE = [ADSI]"LDAP://RootDSE"
# Connect to the Configuration Naming Context
$configSearchRoot = [ADSI]("LDAP://" + `
$rootDSE.Get("configurationNamingContext"))
# Configure the filter
$filter = "(NETBIOSName=*)"
# Search for all partitions where the NetBIOSName is set
$configSearch = New-Object `
DirectoryServices.DirectorySearcher($configSearchRoot, $filter)
# Configure search to return dnsroot and ncname attributes
$retVal = $configSearch.PropertiesToLoad.Add("dnsroot")
$retVal = $configSearch.PropertiesToLoad.Add("ncname")
$configSearch.FindAll() | Select-Object `
@{n="dnsroot";e={$_.Properties.dnsroot}}, `
@{n="ncname";e={$_.Properties.ncname}}
VB .NET
' Connect to RootDSE
Dim RootDSE As New DirectoryEntry("LDAP://rootDSE")
' Retrieve the Configuration Naming Context from RootDSE
Dim configNC As String = _
RootDSE.Properties("configurationNamingContext").Value.ToString()
' Connect to the Configuration Naming Context
Dim configSearchRoot As New DirectoryEntry("LDAP://" & configNC)
' Search for all partitions where the NetBIOSName is set.
Dim configSearch As New DirectorySearcher(configSearchRoot)
configSearch.Filter = ("(NETBIOSName=*)")
' Configure search to return dnsroot and ncname attributes
configSearch.PropertiesToLoad.Add("dnsroot")
configSearch.PropertiesToLoad.Add("ncname")
Dim forestPartitionList As SearchResultCollection
forestPartitionList = configSearch.FindAll()
' Loop through each returned domain in the result collection
For Each domainPartition In forestPartitionList
' domainName like "domain.com". ncName like "DC=domain,DC=com"
Dim domainName As String = _
domainPartition.Properties("dnsroot")(0).ToString()
Dim ncName As String = _
domainPartition.Properties("ncname")(0).ToString()
Next
VbScript
Dim objConnection, objRootDSE, objRecordSet
Dim strFilter
strFilter = "(NETBIOSName=*)"
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objRootDSE = GetObject("LDAP://RootDSE")
Set objRecordSet = objConnection.Execute( _
"<LDAP://" & objRootDSE.Get("configurationNamingContext") & ">;" & _
strFilter & ";" & "dnsroot,ncname;subtree")
Set objRootDSE = Nothing
While Not objRecordSet.EOF
WScript.Echo Join(objRecordSet.Fields("dnsroot").Value)
WScript.Echo objRecordSet.Fields("ncname").Value
objRecordSet.MoveNext
WEnd
No related posts.
Related posts brought to you by Yet Another Related Posts Plugin.
Posted by Oleg on 21.10.08 at 4:00 pm
Hi, thank you for the scripts.
I tried PS and c# codes. They retrieve only one domain in my environment.
But I have 6 domains, if I open my Network Places->Microsoft Windows Networks I see them.
Also, I can retrieve 6 items when I use this code
DirectoryEntry rootEntry = new DirectoryEntry("WinNT:"); foreach (DirectoryEntry child in rootEntry.Children) { listBox1.Items.Add(child.Name); }But I’d like ot use LDAP because of WinNT is legacy provider.
Thanks.
Posted by Daniel Wernle on 21.10.08 at 4:00 pm
A slightly different way to do it is over a search of the trusted Domains. needed it some time ago to search on different domains in a forrest and fill up objects with the “Domain\\Username” notation …
/// /// Gets All Trusted Domains in the Domain Forrest /// public Dictionary GetDomains() { SearchResultCollection srCollection; DirectoryEntry deRoot = new DirectoryEntry(@"LDAP://eu.infineon.com:389/DC=infineon,DC=com"); DirectorySearcher deSearcher = new DirectorySearcher(deRoot); deSearcher.Filter = ("(objectClass=trustedDomain)"); deSearcher.PageSize = 1000; deSearcher.SearchScope = SearchScope.Subtree; srCollection = deSearcher.FindAll(); //ArrayList DomainList = new ArrayList(); Dictionary DomainList = new Dictionary(); foreach (SearchResult se in srCollection) { string currentDomainName = se.GetDirectoryEntry().Name.ToString(); string currentNomainFlatName = se.GetDirectoryEntry().Properties["flatname"].Value.ToString(); currentDomainName = currentDomainName.Replace(".", ",DC="); currentDomainName = currentDomainName.Replace("CN", "DC"); DomainList.Add(currentDomainName,currentNomainFlatName); } return DomainList; }nice article, thx
Posted by Ian Walker on 21.10.08 at 4:00 pm
In the VBScript code, the query on line 12 will fail with a “Table does not exist” error unless “LDAP” is in upper case.
Otherwise, thanks for this, saved me an hour writing it from scratch.
Posted by Chris on 21.10.08 at 4:00 pm
Thanks! Fixed the example.
Chris