Shanky
Shanky

Reputation: 361

Get multiple user with similar names from Active Directory using C#

I need to display a list of users (in autocomplete) with similar names from the AD. For example, if I search Arthur and there are 2 people with same name (first name or last name), I should display both the names in the autocomplete. I tried to get the names but it is taking around 2-4 minutes to get the names. I am using the following code:

        string[] domainNames = new string[] { "domain1", "domain2" };
        List<string> userNames = new List<string>();
        string user = string.Empty;

        foreach (string domain in domainNames)
        {
            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
            {
                GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, "Domain Users");
                if (group != null)
                {
                    foreach (Principal p in group.GetMembers(false))
                    {
                        if (p.Name.ToLower().Contains(key.ToLower()))
                        {
                            if (!userNames.Contains(p.Name))
                                userNames.Add(p.Name);
                        }
                    }
                }
            }
        }

Any way I can speed up the process? I am already using ajax call.

Upvotes: 1

Views: 1140

Answers (2)

Brian Desmond
Brian Desmond

Reputation: 4503

The cn= filter isn't really valid - there's nothing guaranteeing that format. Instead, look up Ambigous Name Resolution - it's designed for this: http://social.technet.microsoft.com/wiki/contents/articles/22653.active-directory-ambiguous-name-resolution.aspx.

Upvotes: 1

Shanky
Shanky

Reputation: 361

        DirectorySearcher ds = new DirectorySearcher();
        ds.SearchRoot = new DirectoryEntry("LDAP://" + domain, domain + @"\" + userName, password);
        ds.Filter = "(&(objectClass=user)(cn=*" + key + "*))";
        ds.PropertyNamesOnly = true;
        ds.PropertiesToLoad.Add("name");
        ds.PropertiesToLoad.Add("cn");

        foreach (SearchResult searchResults in ds.FindAll())
        {
            foreach (string propertyName in searchResults.Properties.PropertyNames)
            {
                foreach (Object retEntry in searchResults.Properties[propertyName])
                {
                    var user = retEntry.ToString().Split('/').Where(x => x.Contains("CN")).Select(y => y).FirstOrDefault().Split(',').Where(z => z.Contains("CN")).Select(c => c).FirstOrDefault().Split(',').FirstOrDefault().Split('=')[1];
                    if(!string.IsNullOrWhiteSpace(user))
                        userNames.Add(user);
                }
            }
        }

Reduced to 30-40 seconds.

Upvotes: 1

Related Questions