给定 UserPrincipal 对象,如何从 Active Directory 中获取“公司”和“部门”?
Posted
技术标签:
【中文标题】给定 UserPrincipal 对象,如何从 Active Directory 中获取“公司”和“部门”?【英文标题】:How to get "Company" and "Department" from Active Directory given a UserPrincipal object? 【发布时间】:2010-12-19 15:15:38 【问题描述】:这可能吗?代码示例会很好。
【问题讨论】:
【参考方案1】:如果用户的部门和公司属性存在,则应该这样做。
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];
【讨论】:
一点点挑剔:在 LDAP 过滤器中,我更喜欢使用“objectCategory”而不是 objectClass。为什么? objectCategory 是单值的,它在 Active Directory 中被索引,因此搜索者使用 objectCategory 更快。 实际上,如果您使用的是 Windows Server 2008,则 objectClass 属性默认会被索引。如果您使用的是 Windows Server 2000 或 2003,则不会。 这是一个很好的解决方案,非常感谢。尽管我正在专门处理 System.DirectoryServices.AccountManagement.UserPrincipal,但我必须将下面的内容标记为正确。【参考方案2】:实际上,问题是如何获取 .NET 3.5 (System.DirectoryServices.AccountManagement.)UserPrincipal
-object 的两个属性,而不是 userPrincipalName
。
这里如何使用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");
上面的代码在大多数情况下都可以工作(也就是说,它适用于标准的文本/字符串单值 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"));
(顺便说一句;这对扩展属性很有用 - too bad it won't be in C# 4 either。)
【讨论】:
您还可以查看 Principal Extensions (msdn.microsoft.com/en-us/library/bb552835.aspx) 以创建具有所需特定属性的自定义主体。 您将如何进行“设置”方法并保存值? @PerNoalt 感谢您的代码,但没有更短的方法可以直接获取属性,例如:直接从 UserPrincipal 获取部门而不使用扩展? 这个扩展太棒了!感谢您发布它。以上是关于给定 UserPrincipal 对象,如何从 Active Directory 中获取“公司”和“部门”?的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 UserPrincipal 类设置 AD-LDS 用户密码
UserPrincipal.GetGroups vs. UserPrincipal.GetAuthorizationGroups?
UserPrincipal.GetAuthorizationGroups() 方法出错
UserPrincipal.FindByIdentity 在 64 位 WinPE 下的 C# 中失败