3

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.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
John John
  • 1
  • 72
  • 238
  • 501
  • Is [this](https://stackoverflow.com/questions/14278274/how-i-get-active-directory-user-properties-with-system-directoryservices-account) what you're looking for? – jAC Jul 13 '17 at 16:11
  • This might be more useful - https://stackoverflow.com/questions/1785751/how-to-get-company-and-department-from-active-directory-given-a-userprincipa – Syntax Error Jul 13 '17 at 16:28

1 Answers1

5

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);
Brett Rigby
  • 6,101
  • 10
  • 46
  • 76
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • How can I get the history of login/logoff for domain controller? I want the IP addresses domain users use to login to server. – immayankmodi Oct 22 '18 at 19:39
  • 1
    If you're using .Net Core, you'll need to add a reference to the System.DirectoryServices package in NuGet - the Principal and DirectoryEntry objects are from there. – Brett Rigby Mar 18 '19 at 14:02
  • ... and the System.DirectoryServices.AccountManagement NuGet package, too. – Brett Rigby Mar 18 '19 at 14:09