Per*_*alt 86

实际上,问题是如何获得.NET 3.5的两个属性 - (System.DirectoryServices.AccountManagement.)UserPrincipal没有给出一个userPrincipalName.

这里有如何使用扩展方法:

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");
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码在大多数情况下都适用(即它适用于标准的Text/String Single-Value Active Directory属性).您需要修改代码并为您的环境添加更多错误处理代码.

您可以通过将"扩展类"添加到项目中来使用它,然后您可以这样做:

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"));
Run Code Online (Sandbox Code Playgroud)

(BTW;这对扩展属性来说非常有用 - 太糟糕了,它也不会在C#4中.)

  • 那个扩展很棒!谢谢您的发布. (2认同)

Mik*_*son 14

如果用户存在部门和公司属性,则应执行此类操作.

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];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 一个小小的挑剔:在LDAP过滤器中,我宁愿使用"objectCategory"而不是objectClass.为什么?objectCategory是单值的,它在Active Directory中被索引,因此使用objectCategory可以更快地搜索到搜索器. (3认同)
  • 实际上,如果您使用的是Windows Server 2008,则默认情况下会对objectClass属性建立索引.如果您使用的是Windows Server 2000或2003,则不会. (2认同)