Moritz Großmann
Moritz Großmann

Reputation: 71

C# Query Active Directory with a custom Property in .NET Standard 2.0

How can I query the Active Directory of my Company with a custom property in .NET Standard2.0? For example, if I want to query with a given property, my code looks like:

FSharpOption<UserPrincipal> TryGetUser(SecurityIdentifier sid)
{
    using (var context = new PrincipalContext(ContextType.Domain))
    {
        var user = UserPrincipal.FindByIdentity(context, IdentityType.Sid, sid.Value);
        if (user == null)
            return FSharpOption<UserPrincipal>.None;

        return FSharpOption<UserPrincipal>.Some(user);
    }
}

Now, I want to query with a custom property named "manager" which is a string. I want to search for all users having the manager == "...".

Upvotes: 1

Views: 2385

Answers (1)

Gabriel Luci
Gabriel Luci

Reputation: 40958

You can't do it with UserPrincipal, and PrincipalSearcher will only let you search by the properties exposed by UserPrincipal. You have to use DirectorySearcher directly (which is what PrincipalSearcher uses behind the scenes anyway).

Here is an example of what you would do:

public IEnumerable<string> GetUsersWithManager(string managerDn) {
    var search = new DirectorySearcher(new DirectoryEntry()) {
        Filter = $"(&(objectClass=user)(manager={managerDn}))"
    };
    search.PropertiesToLoad.Add("distinguishedName");

    using (var results = search.FindAll()) {
        foreach (SearchResult result in results) {
            if (result.Properties.Contains("mail")) {
                yield return (string) result.Properties["distinguishedName"][0];
            }
        }
    }
}

The parameter is the manager's distinguishedName and it returns the distinguishedName of any users who have that person as their manager (the manager attribute contains the DN of the manager's account). You may need to adjust it for your needs.

If you need a UserPrincipal object for the resulting users, you can do that with this (where the distinguishedName variable is the DN of the user):

UserPrincipal.FindByIdentity(context, IdentityType.DistinguishedName, distinguishedName)

Just keep in mind that the manager attribute is not indexed. So if that is your only criteria (besides (objectClass=user)), then AD needs to look at every user to find matches. That may or may not be really slow in your environment.

Personally, I prefer using DirectorySearcher and DirectoryEntry directly anyway. I find the whole System.DirectoryServices.AccountManagement namespace to be really slow. I wrote an article about how to speed up performance using the System.DirectoryServices namespace directly: Active Directory: Better Performance

Upvotes: 2

Related Questions