C# - Look up a users manager in active directory

active-directory, c#

Solution

If you're on .NET 3.5 and up and using the `System.DirectoryServices.AccountManagement` (S.DS.AM) namespace, you can easily extend the existing `UserPrincipal` class to get at more advanced properties, like `Manager` etc.

Read all about it here:

- Managing Directory Security Principals in the .NET Framework 3.5

- MSDN docs on System.DirectoryServices.AccountManagement

Basically, you just define a derived class based on `UserPrincipal`, and then you define your additional properties you want:

[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("Person")]
public class UserPrincipalEx : UserPrincipal
{
    // Inplement the constructor using the base class constructor. 
    public UserPrincipalEx(PrincipalContext context) : base(context)
    { }

    // Implement the constructor with initialization parameters.    
    public UserPrincipalEx(PrincipalContext context,
                         string samAccountName,
                         string password,
                         bool enabled) : base(context, samAccountName, password, enabled)
    {} 

    // Create the "Department" property.    
    [DirectoryProperty("department")]
    public string Department
    {
        get
        {
            if (ExtensionGet("department").Length != 1)
                return string.Empty;

            return (string)ExtensionGet("department")[0];
        }
        set { ExtensionSet("department", value); }
    }

    // Create the "Manager" property.    
    [DirectoryProperty("manager")]
    public string Manager
    {
        get
        {
            if (ExtensionGet("manager").Length != 1)
                return string.Empty;

            return (string)ExtensionGet("manager")[0];
        }
        set { ExtensionSet("manager", value); }
    }

    // Implement the overloaded search method FindByIdentity.
    public static new UserPrincipalEx FindByIdentity(PrincipalContext context, string identityValue)
    {
        return (UserPrincipalEx)FindByIdentityWithType(context, typeof(UserPrincipalEx), identityValue);
    }

    // Implement the overloaded search method FindByIdentity. 
    public static new UserPrincipalEx FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue)
    {
        return (UserPrincipalEx)FindByIdentityWithType(context, typeof(UserPrincipalEx), identityType, identityValue);
    }
}

Now, you can use the "extended" version of the `UserPrincipalEx` in your code:

using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
    // Search the directory for the new object. 
    UserPrincipalEx inetPerson = UserPrincipalEx.FindByIdentity(ctx, IdentityType.SamAccountName, "someuser");

    // you can easily access the Manager or Department now
    string department = inetPerson.Department;
    string manager = inetPerson.Manager;
}        

Problem

Started using the `System.DirectoryServices.AccountManagement` namespace, to perform the lookup on a user in active directory (AD). I also need the user's manager, but I seem to have hit a bump in the road using this namespace. Current code to get a person: ``` class Person { // Fields public string GivenName = null; public string Surname = null; public string DistinguishedName = null; public string Email = null; public string MangerDistinguishedName = null; // Unable to set this // Constructor public Person(string userName) { UserPrincipal user = null; try { user = GetUser(userName); if (user != null) { this.GivenName = user.GivenName; this.Surname = user.Surname; this.DistinguishedName = user.DistinguishedName; this.Email = user.EmailAddress; this.MangerDistinguishedName = user.<NO SUCH PROPERTY TO FIND A MANAGER'S DISTINGUISHED NAME> } else { throw new MissingPersonException("Person not found"); } } catch (MissingPersonException ex) { MessageBox.Show( ex.Message , ex.reason , MessageBoxButtons.OK , MessageBoxIcon.Error ); } catch (Exception ex) { MessageBox.Show( ex.Message , "Error: Possible connection failure, or permissions failure to search for the username provided." , MessageBoxButtons.OK , MessageBoxIcon.Error ); } finally { user.Dispose(); } } ``` Execute search for the person ``` private UserPrincipal GetUser(string userName) { PrincipalContext ctx = new PrincipalContext(ContextType.Domain); UserPrincipal user = UserPrincipal.FindByIdentity(ctx, userName); return user; } ``` What is another way to directly access the distinguished name of the manager of a particular user? - Possible partial answer here in VB, but I see nothing about referring to managers. - Another possible partial one here, again, nothing about managers.

Original source

Related problems