views:

702

answers:

2

Is this possible? Code sample would be nice.

Thanks

+1  A: 

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];
 }
}
Mikael Svenson
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.
marc_s
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.
Per Noalt
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.
wgpubs
+2  A: 

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 extention 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 Extention Properties - too bad it won't be in C# 4 either.)

Per Noalt
Also you might take a look at Principal Extensions (http://msdn.microsoft.com/en-us/library/bb552835.aspx) to create custom principals with the specific properties that you require.
Per Noalt