Pages

Tuesday, January 22, 2013

How to get patronymic from Active Directory

As there is no special field for patronymic in the Active Directory (AD) it is often filled in the Display Name field, while as surname of the user is in the Surname field and his name is in the Given Name field.
So, if you want to import users from the AD with full names and hierarchy, you might try to simply load names, surnames and everything else you need. For patronymics I suggest parse full names: split it by spaces, then remove the name and the surname and join the rest. It should be your patronymic. At least it might be, as administrators might put only reduced forms of a name into display name...
Overral, here is my code, which recursively loads users:

/// 
/// Class for imported users
/// 
public class DomainUser
{
    public string FullName;
    public string Name;
    public string Surname;
    public string Login;
    public string EMail;
    public System.Security.Principal.SecurityIdentifier SID;

    public bool IsOrgUnit;
    public bool IsChecked; //used later for treeview

    public List SubUsers;

    public override string ToString()
    {
        return FullName;
    }
}

public static List GetADUsers(DirectoryEntry root = null)
{
    DirectorySearcher searcher;
    if (root != null)
        searcher = new DirectorySearcher(root);
    else
        searcher = new DirectorySearcher();

    searcher.SearchScope = SearchScope.OneLevel;
    //get only organizational units (for hierarchy) and users-persons
    searcher.Filter = "(|(objectclass=organizationalunit)(&(objectclass=user)(objectcategory=person)))";
            
    List users = new List();

    ResultPropertyValueCollection vc;
    foreach (SearchResult result in searcher.FindAll())
    {
        vc = result.Properties["objectclass"];
        if (vc == null || vc.Count == 0) continue;

        DomainUser currentEntry = new DomainUser();
        currentEntry.IsChecked = true;

        //object class might contain "top" as first entry - so check its actual class with "Contains"
        if (vc.Contains("organizationalUnit"))
        {
            currentEntry.IsOrgUnit = true;

            vc = result.Properties["name"];
            if (vc != null && vc.Count > 0) currentEntry.FullName = vc[0].ToString();

            //as OU can have subusers - look into it:
            currentEntry.SubUsers = GetADUsers(result.GetDirectoryEntry());
        }
        else if (vc.Contains("user"))
        {
            currentEntry.IsOrgUnit = false;

            vc = result.Properties["displayName"];
            if (vc != null && vc.Count > 0) currentEntry.FullName= vc[0].ToString();

            vc = result.Properties["sn"];
            if (vc != null && vc.Count > 0) currentEntry.Surname= vc[0].ToString();

            vc = result.Properties["givenname"];
            if (vc != null && vc.Count > 0) currentEntry.Name = vc[0].ToString();

            vc = result.Properties["objectsid"];
            if (vc != null && vc.Count > 0) currentEntry.SID = new System.Security.Principal.SecurityIdentifier((byte[])vc[0], 0);

            vc = result.Properties["mail"];
            if (vc != null && vc.Count > 0) currentEntry.EMail = vc[0].ToString();

            vc = result.Properties["samAccountName"];
            if (vc != null && vc.Count > 0) currentEntry.Login = vc[0].ToString();
        }

        users.Add(currentEntry);
    }

    return users;
}

private void GetUserFullName(DomainUser user)
{
    //if that user has surname and name - we can try to get its patronymic
    if (!string.IsNullOrEmpty(user.Surname) && !string.IsNullOrEmpty(user.Name))
    {
        string name = user.Name.Trim();
        string surname = user.Surname.Trim();

        List fullNameParts = new List(user.FullName.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries));
        //if there is name and surname in display name
        if (fullNameParts.Remove(name) && fullNameParts.Remove(surname))
        {
            string patronymic = string.Join(" ", fullNameParts);
        }
    }
}

No comments:

Post a Comment