【问题标题】:How to get/update 'Contacts' within Active Directory?如何在 Active Directory 中获取/更新“联系人”?
【发布时间】:2011-02-20 16:18:22
【问题描述】:

有没有办法在 Active Directory 中查找和更新联系人?我正在构建一个示例 C# .NET 应用程序来完成这项任务。我会很感激任何代码。

【问题讨论】:

  • “联系人”是什么意思?什么“联系人”?? AD 存储用户和计算机帐户、安全和通讯组等等 - 但“联系人”是 AD 的一个新术语 - 从未听说过......
  • 联系人就像一个普通的AD对象,比如用户、计算机,它们在Exchange Server中作为邮件联系人出现。在大多数情况下,他们有一个外部电子邮件地址,也就是 smtp 地址。

标签: c# .net active-directory


【解决方案1】:

当然,您可以在 System.DirectoryServices 中完成。

我认为你真正需要的是学习如何使用System.DirectoryServices。如果你还没有一本好书,我推荐this one

这并不难,真的。你只需要掌握两个课程,DirectoryEntryDirectorySearcherDirectoryEntry 代表 LDAP 服务器上的一个 LDAP 对象。假设您有足够的权限,您可以对任何 LDAP 对象进行更改,包括使用DirectoryEntry 的联系人对象。每个 LDAP 对象都有许多属性。您需要知道的两个重要属性是objectCategoryobjectClass。对于联系人对象,objectCategory 应为 personobjectClass 应为 contact。您可能还想检查存储电子邮件地址的联系人对象上的“targetAddress”属性。联系人对象上有一堆 Exchange 扩展属性。您可能喜欢一一检查它们。要浏览 LDAP 服务器上的对象,可以使用 AD ExplorerADSI Edit 之类的工具

要进行搜索,您需要向 DirectorySearcher 提供四件事。

  1. 搜索根
  2. LDAP 搜索过滤器
  3. 搜索范围
  4. 返回的属性

如果您的计算机已加入域,并且您正在以域用户身份登录,这里有一个示例,说明如何列出域中的所有联系人。

DirectoryEntry rootDSE = new DirectoryEntry("LDAP://RootDSE");
string domainContext = rootDSE.Properties["defaultNamingContext"].Value as string;
DirectoryEntry searchRoot = new DirectoryEntry("LDAP://" + domainContext);
using (DirectorySearcher searcher = new DirectorySearcher(
    searchRoot, 
    "(&(objectCategory=person)(objectClass=contact))", 
    new string[] {"targetAddress"}, 
    SearchScope.Subtree))
{
    foreach (SearchResult result in searcher.FindAll())
    {
        foreach (string addr in result.Properties["targetAddress"])
        {        
           Console.WriteLine(addr);
        }
        Console.WriteLine(result.Path);
    }
}

前三行用于帮助您找到指向域根目录的正确 LDAP 路径。它仅在您以域用户身份登录时才有效。如果您知道域的正确 LDAP 路径,则可以直接将其输入 DirectoryEntry。

我将所有四个参数都放入DirectorySearcher。当您熟悉目录服务编程时,您可以跳过其中的一些,.NET 将为您提供一个默认值。

DiectorySearcher 返回的结果是SearchResult。请注意,SearchResult 总是向您返回一个对象集合,即使 targetAddress 不是多值属性。这是因为 LDAP 对象上的某些属性可能是多值的。

您可以从SearchResult 获得的另一个重要信息是Path。您可以稍后使用此路径创建一个DirectoryEntry 对象。要更新您的联系人对象,您需要使用其Properties 方法和CommitChanges 方法。

DirectoryEntry de = new DirectoryEntry(result.Path);
de.Properties["targetAddress"].Value = "SMTP:jane.doe@foo.bar";
de.CommitChanges();

最后,您实际上可以很容易地在DirectorySearcherDirectoryEntry 上找到很多在线教程。试试谷歌吧。

【讨论】:

  • 非常感谢您的详细回复。问题仍然是如何将多个电子邮件地址添加到联系人的对象。
【解决方案2】:

我认为您的意思是更新 Active Directory 中用户对象的属性。是的,这是可能的。

在 .Net 3.5 中,我们获得了 System.DirectoryServices.AccountManagement 命名空间,与之前的 System.DirectoryServices 命名空间相比,这使得处理 AD 变得更加简单。

通常要修改用户的属性(如果您有权保存),您会执行以下操作:

string sUserName = "someusertoload";
string sDomain = "test.local";
string sDefaultOU = "OU=test,DC=test,DC=local";
string sServiceUser = "userwithrights";
string sServicePassword = "somepassword";
PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain, sDomain, sDefaultOU,ContextOptions.SimpleBind, sServiceUser, sServicePassword);
UserPrincipal oUserPrincipal = UserPrincipal.FindByIdentity(oPrincipalContext, sUserName);
oUserPrincipal.GivenName = "new givenname";
oUserPrincipal.Save();

你可以找到一些辅助方法here

.Net 2.0 的代码示例检索用户名为“john”的用户并更新用户的街道地址。如果运行应用的用户无权编辑内容,您可能必须在第一行添加凭据。

DirectoryEntry root = new DirectoryEntry("LDAP://server/DC=test,DC=local");
DirectorySearcher searcher = new DirectorySearcher( root, "(&(objectCategory=person)(objectClass=user)(sAMAccountName=john))" );
SearchResult result = searcher.FindOne();
DirectoryEntry user = result.GetDirectoryEntry();
user.Properties["streetAddress"][0] = "My Street 12";
user.CommitChanges();

【讨论】:

  • 嗨,Mikael,非常感谢您的回复。我仍在处理一个仍在 .NET 2.0 上的项目。我真的希望我能找到使用 System.DirectoryServices 的方法。我很感激你的回复。如果您有什么要与 System.DirectoryService 分享的内容,请随时分享。出于礼貌,我接受它作为答案:)
  • 为您的观赏乐趣添加了一个示例 :)
  • 发帖人指的是联系人。据我所知 System.DirectoryServices.AccountManagement 无法与联系人一起使用
  • System.DirectoryServices.AccountManagement 可以获取和更新联系人(我已经验证过了)。但是它不能创建 联系人,只能是用户。它也不能在一个 LDAP 请求中根据对象 guid 选择多个用户/联系人。
  • @ITHitWebDAV 我真的很好奇使用 AccountManagement 获取属于通讯组成员的联系人。如果这是您已验证的内容,您能否提供有关如何完成的提示或参考。我没有找到任何关于此功能的参考
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 2019-11-06
  • 2016-06-18
  • 1970-01-01
  • 2017-09-07
相关资源
最近更新 更多