scd
scd

Reputation: 73

How to retrieve all users across all domains, and subdomain in a multiple domain Active Directory

We are attempting to retrieve a list of all users in Active Directory (across all domains in a multiple-domain scenario) and within all sub-domains.

We use code similar to the following.

We assumed that our customers could configure their domain with port 3268 (global catalog), and the code would retrieve all users in all domains. The following code does return users, but it is limited to one domain.

Question 1: Why doesn't the Global Catalog contain all users in all domains?

Question 2: Some research has suggested I need to provide a container to search a specific domain. If that is the case, what value is the Global Catalog when I could just as easily connect to the other domain?

Question 3: Is there a generic way to search all users across all domains?

namespace TestApplication
{
    public static class StringMethods
    {
        public static string ValueOrNull(this string source)
        {
            return string.IsNullOrWhiteSpace(source) ? null : source;
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            string server = null;    // domain controller machine name, domain name, or domain:3268 (Global Catalog LDAP) and domain:3269 (Global Catalog LDAPS)
            string container = null; // root of search
            string username = null;  // username to connect to active directory or null for default
            string password = null;  // password of username to connec to to active directory or null for default.

            // attributes to retrieve
            string[] attributes = new string[] { "userPrincipalName", "msds-PrincipalName", "displayName", "distinguishedName", "mail" };

            // change this to your domain
            server = "domain:3268";  // use global catalog
            
            try
            {
                PrincipalContext principalContext = new PrincipalContext(
                    ContextType.Domain,
                    server.ValueOrNull(),
                    container.ValueOrNull(),
                    username.ValueOrNull(),
                    password.ValueOrNull());

                using (principalContext)
                {
                    using (UserPrincipal userPrincipal = new UserPrincipal(principalContext))
                    {
                        using (PrincipalSearcher principalSearcher = new PrincipalSearcher(userPrincipal))
                        {
                            DirectorySearcher underlyingSearcher = (DirectorySearcher)principalSearcher.GetUnderlyingSearcher();
                            underlyingSearcher.PropertiesToLoad.Clear();
                            underlyingSearcher.PropertiesToLoad.AddRange(attributes);
                            underlyingSearcher.SizeLimit = 0;
                            underlyingSearcher.Sort = new SortOption("displayName", SortDirection.Descending);

                            using (SearchResultCollection searchResultCollections = underlyingSearcher.FindAll())
                            {
                                if (searchResultCollections.Count != 0)
                                {
                                    foreach (SearchResult searchResult in searchResultCollections)
                                    {
                                        Console.WriteLine("------------------------------------------------");
                                        // Loop over the properties for each user returned.
                                        foreach (string propertyName in searchResult.Properties.PropertyNames)
                                        {
                                            ResultPropertyValueCollection item = searchResult.Properties[propertyName];
                                            if (item.Count < 1)
                                            {
                                                Console.WriteLine(propertyName + " : {null}");
                                            }
                                            else if (item.Count == 1)
                                            {
                                                Console.WriteLine(propertyName + " : " + item[0]);
                                            }
                                            else
                                            {
                                                Console.WriteLine(propertyName + ": ");
                                                foreach (var propertyValue in item)
                                                {
                                                    Console.WriteLine(propertyValue.ToString().PadLeft((propertyName + " :").Length));
                                                }
                                            };
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
    }
}

Upvotes: 0

Views: 158

Answers (0)

Related Questions