Search code examples
c#asp.netdirectoryservicesuserprincipal

Can I get the User Department from Active Directory using PrincipalContext()


I am trying to get the user's department from Active Directory. I have the following class:

public class DomainContext
{
        public string DisplayName { get; set; }
        public string Name { get; set; }
        public string SamAccountName { get; set; }
        public string DistinguishedName { get; set; }
        public string UserPrincipalName { get; set; }
        public string Department { get; set; }
}

Then using the below method, I am able to get the user name, display name, sam account, etc....

public override void getUserDepts(SPItemEventProperties properties)
{
    base.ItemUpdating(properties);

    string[] offices = new string[] { "OfficeA", "OfficeB", "OfficeC" };

    string ADServerName = "*****";
    string ADusername = "******";
    string ADpassword = "*****";

    using (var context = new PrincipalContext(ContextType.Domain, ADServerName, ADusername, ADpassword))
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        var searchResults = searcher.FindAll();

        foreach (Principal p in searchResults)
        {
            if (p.DistinguishedName.ToLower().Contains(offices[0].ToLower()) || p.DistinguishedName.ToLower().Contains(offices[1].ToLower()) || p.DistinguishedName.ToLower().Contains(offices[2].ToLower())))
            {
                DomainContext dc = new DomainContext();
                dc.DisplayName = p.DisplayName;
                dc.UserPrincipalName = p.UserPrincipalName;
                dc.Name = p.Name;
                dc.SamAccountName = p.SamAccountName;
                dc.DistinguishedName = p.DistinguishedName;
                // dc.Department = p. **CAN NOT GET THE DEPARTMENT NAME**
            }
        }
    }
}

but I am unable to locate how I can get the department name.


Solution

  • You can access the department by checking its underlying properties in its DirectoryEntry

    var property = "department";
    var directoryEntry = p.GetUnderlyingObject() as DirectoryEntry;
    if (directoryEntry.Properties.Contains(property)) {
        dc.Department = directoryEntry.Properties[property].Value.ToString();
    }
    

    You could consider converting the above into an extension method to reduce the repeated code.

    I compiled a list of user properties into a class as constants

    public static class ADUserProperties
    {
        public const String OBJECTCLASS = "objectClass";
    
        public const String CONTAINERNAME = "cn";
    
        public const String LASTNAME = "sn";
    
        public const String COUNTRYNOTATION = "c";
    
        public const String CITY = "l";
    
        public const String STATE = "st";
    
        public const String TITLE = "title";
    
        public const String POSTALCODE = "postalCode";
    
        public const String PHYSICALDELIVERYOFFICENAME = "physicalDeliveryOfficeName";
    
        public const String FIRSTNAME = "givenName";
    
        public const String MIDDLENAME = "initials";
    
        public const String DISTINGUISHEDNAME = "distinguishedName";
    
        public const String INSTANCETYPE = "instanceType";
    
        public const String WHENCREATED = "whenCreated";
    
        public const String WHENCHANGED = "whenChanged";
    
        public const String DISPLAYNAME = "displayName";
    
        public const String USNCREATED = "uSNCreated";
    
        public const String MEMBEROF = "memberOf";
    
        public const String USNCHANGED = "uSNChanged";
    
        public const String COUNTRY = "co";
    
        public const String DEPARTMENT = "department";
    
        public const String COMPANY = "company";
    
        public const String PROXYADDRESSES = "proxyAddresses";
    
        public const String STREETADDRESS = "streetAddress";
    
        public const String DIRECTREPORTS = "directReports";
    
        public const String NAME = "name";
    
        public const String OBJECTGUID = "objectGUID";
    
        public const String USERACCOUNTCONTROL = "userAccountControl";
    
        public const String BADPWDCOUNT = "badPwdCount";
    
        public const String CODEPAGE = "codePage";
    
        public const String COUNTRYCODE = "countryCode";
    
        public const String BADPASSWORDTIME = "badPasswordTime";
    
        public const String LASTLOGOFF = "lastLogoff";
    
        public const String LASTLOGON = "lastLogon";
    
        public const String PWDLASTSET = "pwdLastSet";
    
        public const String PRIMARYGROUPID = "primaryGroupID";
    
        public const String OBJECTSID = "objectSid";
    
        public const String ADMINCOUNT = "adminCount";
    
        public const String ACCOUNTEXPIRES = "accountExpires";
    
        public const String LOGONCOUNT = "logonCount";
    
        public const String LOGINNAME = "sAMAccountName";
    
        public const String SAMACCOUNTTYPE = "sAMAccountType";
    
        public const String SHOWINADDRESSBOOK = "showInAddressBook";
    
        public const String LEGACYEXCHANGEDN = "legacyExchangeDN";
    
        public const String USERPRINCIPALNAME = "userPrincipalName";
    
        public const String EXTENSION = "ipPhone";
    
        public const String SERVICEPRINCIPALNAME = "servicePrincipalName";
    
        public const String OBJECTCATEGORY = "objectCategory";
    
        public const String DSCOREPROPAGATIONDATA = "dSCorePropagationData";
    
        public const String LASTLOGONTIMESTAMP = "lastLogonTimestamp";
    
        public const String EMAILADDRESS = "mail";
    
        public const String MANAGER = "manager";
    
        public const String MOBILE = "mobile";
    
        public const String PAGER = "pager";
    
        public const String FAX = "facsimileTelephoneNumber";
    
        public const String HOMEPHONE = "homePhone";
    
        public const String MSEXCHUSERACCOUNTCONTROL = "msExchUserAccountControl";
    
        public const String MDBUSEDEFAULTS = "mDBUseDefaults";
    
        public const String MSEXCHMAILBOXSECURITYDESCRIPTOR = "msExchMailboxSecurityDescriptor";
    
        public const String HOMEMDB = "homeMDB";
    
        public const String MSEXCHPOLICIESINCLUDED = "msExchPoliciesIncluded";
    
        public const String HOMEMTA = "homeMTA";
    
        public const String MSEXCHRECIPIENTTYPEDETAILS = "msExchRecipientTypeDetails";
    
        public const String MAILNICKNAME = "mailNickname";
    
        public const String MSEXCHHOMESERVERNAME = "msExchHomeServerName";
    
        public const String MSEXCHVERSION = "msExchVersion";
    
        public const String MSEXCHRECIPIENTDISPLAYTYPE = "msExchRecipientDisplayType";
    
        public const String MSEXCHMAILBOXGUID = "msExchMailboxGuid";
    
        public const String NTSECURITYDESCRIPTOR = "nTSecurityDescriptor";
    
    }
    

    and created an extension method to access it

    public static string GetProperty(this DirectoryEntry directoryEntry , string propertyName, int index = 0) {
        if (directoryEntry.Properties.Contains(propertyName) && index > -1 && index < directoryEntry.Properties[propertyName].Count) {
            return directoryEntry.Properties[propertyName][index].ToString();
        } else {
            return string.Empty;
        }
    }
    
    public static string GetProperty(this Principal principal, string property) {
        var directoryEntry = principal.GetUnderlyingObject() as DirectoryEntry;
        return directoryEntry.GetProperty(property);
    }
    

    This would then allow your code to be updated to

    dc.Department = p.GetProperty(ADUserProperties.DEPARTMENT);