How can I better query multiple domains in Active Directory using C#?

后端 未结 2 1218
既然无缘
既然无缘 2021-01-06 17:09

I am attempting to expand a LDAP / AD search from only searching in the currently logged in domain to searching all domains in the AD. The method takes in the string with th

2条回答
  •  失恋的感觉
    2021-01-06 17:44

    @Brian Desmond and @lordzero. Possibly a bit late to the part here, but I've just been working on this sort of stuff myself recently so thought I share.

    In response to your question 'What's your search root?", lordzero, here's what you can do to find it from the AD servers without knowing them. A Domain registered PC will know the AD infrastructure/Forest etc.

    First you create a DirectoryEntry for "GC://rootDSE" from that you extract a Naming Context, rootDomainNamingContext or another. You can dump out all the attributes of the first root DSE DirectoryEntry to see what's available.

    This is my implementation for a Directory Services service provider we use.

    This is taken from a DirectorySearcherWrapper class

    I have a member var. and instantiate it in the constructor.

    DirectorySearcher directorySearcher;
    

    In my initialisation method, I do this

            using (DirectoryEntry directoryEntry = new DirectoryEntry(DirectoryConstants.RootDSE))
            {
                // Create a Global Catalog Directory Service Searcher
                string strRootName = directoryEntry.Properties[DirectoryConstants.RootDomainNamingContext].Value.ToString();
                using (DirectoryEntry usersBinding = new DirectoryEntry(DirectoryConstants.GlobalCatalogProtocol + strRootName))
                {
                    directorySearcher.SearchRoot = usersBinding;
                    directorySearcher.ClientTimeout = timeout;
                    directorySearcher.CacheResults = true;
                    result = true;
                    initialized = true;
                }
            }
    

    DirectoryConstants class properties

    public static string RootDSE { get { return @"GC://rootDSE"; } }
    public static string RootDomainNamingContext { get { return "rootDomainNamingContext"; } }
    public static string GlobalCatalogProtocol { get { return @"GC://"; } }
    

    I'm sure this only works for Domain users logged in to a Domain registered PC. Authentication is automatically handled behind the scenes. If your user is logged in to a local account or the machine isn't on a Domain, you'll most likely get a DirectoryServicesCOMException.

    Hope this helps. Ditch the 'using' constructs if you're not bothered about disposal and StyleCop/Sonar coding violations!

    The DirectorySearcherWrapper class where the code above resides is then used by the service provider code. It's separated like this so it can easily be Mocked out as there no guarantee the build machines are registered to a domain when it executes our Unit Tests.

    ...most of it comes from the MSDN/.Net documentation.

提交回复
热议问题