【问题标题】:Using DirectoryServices.AccountManagement, how do I get the e-mail address of an active directory security group?使用 DirectoryServices.AccountManagement,我如何获取 Active Directory 安全组的电子邮件地址?
【发布时间】:2013-01-07 15:04:39
【问题描述】:

我在 Active Directory 中有一个安全组(如下图所示),它有一个与之关联的电子邮件地址。如何获取群组的电子邮件地址? GroupPrincipal 对象上没有任何电子邮件地址属性。

这就是我检索所有组的方式:

using (PrincipalContext context = new PrincipalContext(DirectoryContextType, Domain)) {
    using (var groupSearcher = new GroupPrincipal(context)) {
        using (var searcher = new PrincipalSearcher(groupSearcher)) {
            foreach (GroupPrincipal group in searcher.FindAll()) {
                //How do I get the e-mail address?
            }
        }
    }
}

【问题讨论】:

  • 该组是否有与之关联的用户名?我不了解组,但我在与用户打交道时使用 UserPrincipal。
  • @Anon - 该组有一个 samaccountname 活动目录属性。搜索由 UserPrincipal 过滤的对象不会返回该对象,因为它是一个组。我上面给出的代码检索了组,但是,我无权访问对象上的电子邮件地址。
  • @JustinHelgerson 您可以将组成员转换为UserPrincipal,因为他们共享一个界面;请看下面我的回答

标签: c# .net active-directory directoryservices


【解决方案1】:

我只是想在此处添加此内容,因为我认为它可能会有所帮助。 帐户管理库非常适合快速执行重置 AD 用户密码或获取常用属性等操作。但它绝对没有所有这些。 我所做的是获取基础目录对象,就像这样......

// Pretend you have a groupprincipal object called 'group' 
// This will get all of the properties of that group object not accounted for in 
// System.DirectoryServices.AccountManagement
DirectoryEntry groupDE = group.GetUnderlyingObject() as DirectoryEntry();
// We all know that a distro group in AD will have at least 1 email address. 
// However, A
// security group will have 0, and since the mail property is of type
// PropertyValueCollection, if you try to access the first member of the collection
// and it has no length, an exception will be thrown. The following code 
// accounts for this problem. 

// Get the mail attribute of the AD object 
PropertyValueCollection group_email_addresses = groupDe.Properties["mail"];
// Make sure there is at least one address
if (group_email_addresses.Count > 0){
   // knowing that you have at least one address, you can access the first entry or 
   // loop and grab all entries on a property, depending on the appropriate use case
   Console.WriteLine(group_email_addresses[0]); 
} 

// 这个概念可以应用于所有的主体对象。只需寻找 // GetUnderlyingObject() 方法开始!

【讨论】:

    【解决方案2】:

    如果您想从账户管理中执行此操作,您需要make a new class that exposes that property

    [DirectoryObjectClass("group")]
    [DirectoryRdnPrefix("CN")]
    public class GroupPrincipalsEx : GroupPrincipal
    {
        public GroupPrincipalsEx(PrincipalContext context) : base(context) { }
    
        public GroupPrincipalsEx(PrincipalContext context, string samAccountName)
            : base(context, samAccountName)
        {
        }
    
        [DirectoryProperty("mail")]
        public string EmailAddress
        {
            get
            {
                if (ExtensionGet("mail").Length != 1)
                    return null;
    
                return (string)ExtensionGet("mail")[0];
    
            }
            set { this.ExtensionSet("mail", value); }
        }
    }
    

    【讨论】:

    • 无法将 ...GroupPrincipal 类型的对象转换为 GroupPrincipalsEx 类型
    【解决方案3】:

    您需要将所有内容都转换为 UserPrincipal 类型:

    var mailList = new List<MailAddress>();
    var adDomain = "yourdomain";
    var adGroup = "yourgroup";
    
    using (var context = new PrincipalContext(ContextType.Domain, adDomain))
    {
        using (var groupContext = GroupPrincipal.FindByIdentity(context, adGroup))
        {
            mailList = groupContext.GetMembers(true)
                                   .Cast<UserPrincipal>()
                                   .Where(x => !string.IsNullOrEmpty(x.EmailAddress) && !string.IsNullOrEmpty(x.DisplayName))
                                   .Select(x => new MailAddress(x.EmailAddress, x.DisplayName))
                                   .ToList();
        }
    
    }
    
    return mailList;
    

    【讨论】:

    • @Hill 您的帐户可能无权访问该 AD 组中的任何其他成员。
    猜你喜欢
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    相关资源
    最近更新 更多