How to get "Company" and "Department" from Active Directory given a UserPrincipal object?
Asked Answered
P

2

35

Is this possible? Code sample would be nice.

Physiography answered 23/11, 2009 at 20:32 Comment(0)
F
96

Actually, the question was how to get two of the properties for a .NET 3.5 (System.DirectoryServices.AccountManagement.)UserPrincipal-object not given a userPrincipalName.

Here how to do that with an extension method:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace MyExtensions
{
    public static class AccountManagementExtensions
    {

        public static String GetProperty(this Principal principal, String property)
        {
            DirectoryEntry directoryEntry = principal.GetUnderlyingObject() as DirectoryEntry;
            if (directoryEntry.Properties.Contains(property))
                return directoryEntry.Properties[property].Value.ToString();
            else
                return String.Empty;
        }

        public static String GetCompany(this Principal principal)
        {
            return principal.GetProperty("company");
        }

        public static String GetDepartment(this Principal principal)
        {
            return principal.GetProperty("department");
        }

    }
}

The above code will work in most cases (that is it will work for standard Text/String Single-Value Active Directory attributes). You'll need to modify the code and add more error handling code for your environment.

You use it by add the "Extension Class" to your project and then you can do this:

PrincipalContext domain = new PrincipalContext(ContextType.Domain);
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(domain, "youruser");
Console.WriteLine(userPrincipal.GetCompany());
Console.WriteLine(userPrincipal.GetDepartment());
Console.WriteLine(userPrincipal.GetProperty("userAccountControl"));

(BTW; this would have been a great use for Extension Properties - too bad it won't be in C# 4 either.)

Florencia answered 24/11, 2009 at 9:0 Comment(4)
Also you might take a look at Principal Extensions (msdn.microsoft.com/en-us/library/bb552835.aspx) to create custom principals with the specific properties that you require.Florencia
how would you go about doing a "Set" method and saving a value?Fluxion
@PerNoalt Thanks for code but isn't there a shorter way to directly get a property eg: department from UserPrincipal directly without using extensions?Maneater
That extension is awesome! Thank you for posting it.Ellsworthellwood
M
15

Something like this should do it if the department and company properties exist for the user.

DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://dnsNameOfYourDC.my.company.com";
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.PropertiesToLoad.Add("department");
deSearch.PropertiesToLoad.Add("company");

deSearch.SearchScope = SearchScope.Subtree;
deSearch.Filter = "(&(objectClass=User)(userPrincipalName=MyPrincipalName))";
SearchResultCollection results = deSearch.FindAll():

foreach (SearchResult result in results)
{
    ResultPropertyCollection props = result.Properties;
    foreach (string propName in props.PropertyNames)
    {
       //Loop properties and pick out company,department
       string tmp = (string)props[propName][0];
    }
}
Maim answered 23/11, 2009 at 21:16 Comment(3)
one little nitpick: in the LDAP filter, I would prefer to use the "objectCategory" instead of objectClass. Why? The objectCategory is single-valued, and it's indexed in Active Directory, thus searcher are faster using objectCategory.Burnisher
Actually, the objectClass-attribute is indexed by default if you're on Windows Server 2008. It's not if you on Windows Server 2000 or 2003.Florencia
This is a great solution and works so thanks. I had to mark the one below as correct though as I'm dealing with System.DirectoryServices.AccountManagement.UserPrincipal specifically.Physiography

© 2022 - 2024 — McMap. All rights reserved.