代码之家  ›  专栏  ›  技术社区  ›  SqlRyan

使用DirectoryServices“member”属性时,“域用户”组为空

  •  8
  • SqlRyan  · 技术社区  · 16 年前

    我正在使用以下代码获取域上组的成员:

      Dim de As New DirectoryEntry("LDAP://" & GroupDN)
    
      For Each user As String In CType(de.Properties("member"), IEnumerable)
    
              GroupCollection.Add(Username, Username)
    
      Next
    

    我的问题是,当GroupDN(组的可分辨名称)为“ CN=域用户,CN=用户,DC=Mydomain,DC=local ,For…Each循环不会执行,当我手动检查Properties语句时,它的计数为零。这似乎适用于我域中的其他所有组,但“domain Users”组应该包含所有人,并且似乎不包含任何人。

    我检查过了,小组在我的Windows广告工具中正确列出了所有人。这里有什么明显的我遗漏的吗?另一方面,有没有更好的方法让团队中的所有成员都参与进来?

    1 回复  |  直到 16 年前
        1
  •  11
  •   tvanfosson    16 年前

    除非更改用户的主组id,否则该用户不会存储在域用户组的成员属性中,而是使用主组id设置为域用户RID的事实来确定域用户中的成员身份。通常情况下,域用户成员属性为空;这将要求您对默认的Active Directory实现进行一些更改,以避免出现这种情况。

    域用户组使用 基于 要访问的用户的“主组ID” 确定成员资格,而不是 通常将成员存储为 多值链接属性。如果 用户的主组已更改, 他们在域用户中的成员身份 计算时间更长。这对我来说是真的 Windows 2000,但尚未更改 WindowsServer2003。

    Reference

        2
  •  0
  •   marsh-wiggle    4 年前

    这个 accepted answer 513 在属性中设置 primarygroupid Domain Users sid . 但是:这是可以更改的,其他组都可以在那里配置,所以我们不能依赖它。

    下面是一个示例方法,用于获取 group members 无论如何(无论是否保留或更改默认设置)。我调用这样的方法 在查询active directory组的成员后 . 在本例中,我得到一个可分辨名称数组作为结果。但所有其他属性都是可能的,只需将它们添加到 dSearcher.PropertiesToLoad.Add(...) 并修改结果。

    我知道,这是一个关于VB的问题,我希望它很容易移植。

    
        using System.DirectoryServices;
        using System.Security.Principal;
    
    
        public static string[] GetMembersDnByPrimaryGroupId(string domainName, SecurityIdentifier sidOfGroupToGetMembersByPrimaryGroupId)
        {
            // In a single domain environement the domain name is probably not needed, but
            // we expect a multy domain environement
            if (string.IsNullOrWhiteSpace(domainName) || sidOfGroupToGetMembersByPrimaryGroupId == null)
            {
                throw new ArgumentNullException($"Neither domainName nor sid may be null / blank: DomainName: { domainName }; sid: { sidOfGroupToGetMembersByPrimaryGroupId }");
                //<----------
            }
    
            List<string> membersDnResult = new List<string>();
            // Get the last segment of the group sid, this is what is stored in the "primaryGroupId"
            string groupSidTail = sidOfGroupToGetMembersByPrimaryGroupId.Value.Split('-').Last();
            string path = $"LDAP://{ domainName }";
            DirectoryEntry dEntry = new DirectoryEntry(path);
    
            SearchResultCollection adSearchResult = null;
            DirectorySearcher dSearcher = new DirectorySearcher(dEntry);
    
            // For this example we need just the distinguished name but you can add
            // here the property / properties you want
            dSearcher.PropertiesToLoad.Add("distinguishedName");
    
            // set the filter to primarygroupid
            dSearcher.Filter = $"(&(primarygroupid={ groupSidTail }))";
    
            // May die thousand deaths, therefore exception handling is needed. 
            // My exception handling is outside of this method, you may want
            // to add it here
            adSearchResult = dSearcher.FindAll();
    
            // Get the domains sid and check if the domain part of the wanted sid
            // fits the domain sid (necesarry in multy domain environments)
            byte[] domainSidBytes = (byte[])dEntry.Properties["objectSid"].Value;
            SecurityIdentifier domainSid = new SecurityIdentifier(domainSidBytes, 0);
            if (sidOfGroupToGetMembersByPrimaryGroupId.AccountDomainSid != domainSid)
            {
                throw new ArgumentException($"Domain sid of the wanted group { sidOfGroupToGetMembersByPrimaryGroupId.AccountDomainSid } does not fit the sid { domainSid } of the searched through domain \"{ domainName }\"");
                //<----------
            }
    
            // We found entries by the primarygroupid
            if (adSearchResult.Count > 0)
            {
                foreach (SearchResult forMemberByPrimaryGroupId in adSearchResult)
                {
                    // Every AD object has a distinguishedName, therefore we acess "[0]" 
                    // wihtout any further checking
                    string dn = forMemberByPrimaryGroupId.Properties["distinguishedName"][0].ToString();
                    membersDnResult.Add(dn);
                }
            }
    
            return membersDnResult.ToArray();
        }