【问题标题】:How to get Active Directory Attributes not represented by the UserPrincipal class如何获取未由 UserPrincipal 类表示的 Active Directory 属性
【发布时间】:2010-10-14 02:11:29
【问题描述】:

我的意思是,我现在正在使用 System.DirectoryServices.AccountManagement,如果我使用 UserPrincipal 类,我只会看到名称、中间名等

所以在我的代码中是这样的

UserPrincipal myUser = new UserPrincipal(pc);
myUser.Name = "aaaaaa";
myUser.SamAccountName = "aaaaaaa";
.
.
.
.
myUser.Save();

如何查看 mobile 或 info 等属性?

【问题讨论】:

    标签: c# active-directory directoryservices


    【解决方案1】:

    在这种情况下,您需要更深一层 - 回到 DirectoryEntry 的内部 - 通过从用户主体那里获取它:

    using (DirectoryEntry de = myUser.GetUnderlyingObject() as DirectoryEntry)
    {
        if (de != null)
        {
            // Go for those attributes and do what you need to do...
            var mobile = de.Properties["mobile"].Value as string;
            var info = de.Properties["info"].Value as string;
        }
    }
    

    【讨论】:

    • 这作为一个快速修复工作正常,但我试图避免使用目录条目。感谢您的帮助
    • 很惊讶这得到了如此多的支持,因为它没有显示如何实现 de 对象来获取属性。
    • 这里是一个获取Common-Name de.Properties["cn"].Value.ToString();的例子
    • 我比接受的答案更喜欢这个答案。这涉及的内容要少得多,并且可以为您提供精美的信息。
    • 如果我想在“组织”选项卡下拉一些字段,我如何找到属性名称?谢谢。
    【解决方案2】:

    正确的做法是使用PrincipalExtensions 扩展您所追求的Principal 并使用ExtensionSet 和ExtensionGet 方法,如here 所述。

    【讨论】:

      【解决方案3】:

      up.Mobile 会很完美,但不幸的是,UserPrincipal 类中没有这样的方法,所以你必须通过调用 .GetUnderlyingObject() 来切换到 DirectoryEntry。

      static void GetUserMobile(PrincipalContext ctx, string userGuid)
      {
          try
          {
              UserPrincipal up = UserPrincipal.FindByIdentity(ctx, IdentityType.Guid, userGuid);
              DirectoryEntry up_de = (DirectoryEntry)up.GetUnderlyingObject();
              DirectorySearcher deSearch = new DirectorySearcher(up_de);
              deSearch.PropertiesToLoad.Add("mobile");
              SearchResultCollection results = deSearch.FindAll();
              if (results != null && results.Count > 0)
              {
                  ResultPropertyCollection rpc = results[0].Properties;
                  foreach (string rp in rpc.PropertyNames)
                  {
                      if (rp == "mobile")
                          Console.WriteLine(rpc["mobile"][0].ToString());
                  }
              }
          }
          catch (Exception ex)
          {
              Console.WriteLine(ex.ToString());
          }
      }
      

      【讨论】:

      • 不幸的是,如果您在 deSearch 上加载一个在 AD 中具有空值的属性,它不会在结果集中返回,并且原始代码不会检查它是否不存在,所以它在Console.WriteLine 行上抛出异常Object reference not set to an instance of an object。我提交了应该完成这项工作的编辑。
      • 请注意,这都应该包含在try...catch 中。如果一个用户被发送到这个不再在 AD 中的函数,它也会在 DirectoryEntry 实例化上得到异常 Object reference not set to an instance of an object - 在我的编辑中也更正了这个。
      • 另外,我什至在results 的rootSearch 的可能属性名称列表中都没有看到“mobile”。 telephonenumber 可能实际上是 OP 正在寻找的东西。它与 AD 中用户的 GUI 表单中的“电话”相同,但也与 up.VoiceTelephoneNumber 相同,因此甚至不需要 .GetUnderlyingObject() 调用。但其他属性可能会,所以对我来说,这是遍历它们的最佳解决方案。
      • 为什么使用DirectorySearcher?使用 de.Properties ? var mobile = de.Properties["mobile"].Value as string;
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 2010-12-19
      相关资源
      最近更新 更多