当我使用DirectoryServices“member”属性时,“Domain Users”组为空

时间:2009-02-08 02:30:54

标签: vb.net active-directory directoryservices

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

  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 =本地”时,For ... Each循环不执行,当我手动检查属性语句时,它的计数为零。这似乎适用于我的域中的每个其他组,但“域用户”组应该包含所有人,并且它似乎包含任何人。

我已经检查过了,该小组在我的Windows AD工具中正确列出了所有人。我有什么明显的遗漏吗?另外,有没有更好的方法来获得一个小组的所有成员?

2 个答案:

答案 0 :(得分:9)

除非您更改用户的主要组ID,否则用户不会存储在Domain Users组的成员属性中,而是使用主要组ID设置为域用户RID以确定成员身份的事实。域用户。正常情况是Domain Users成员属性为空;它需要您对默认的Active Directory实现进行一些更改,但事实并非如此。

  

Domain Users组使用   基于“计算”机制   用户的“主要组ID”   确定会员资格而不是   通常将成员存储为   多值链接属性。如果   用户的主要组已更改,   他们在Domain Users中的会员资格   组被写入链接   该组的属性是否定的   更长的计算。这是真的   Windows 2000并没有改变   Windows Server 2003。

Reference

答案 1 :(得分:0)

accepted answer 是绝对正确的。默认情况下,每个(用户)对象都在属性 primarygroupid 中设置了 513,这是 Domain Users sid 的固定“尾部”。但是:这可以改变,其他每个组都可以在那里配置,所以我们不能依赖它。

这里是如何获取 group members 的示例方法(无论是否保留或更改默认值)。我在对活动目录组成员进行任何查询后调用这样的方法。在这个例子中,我得到了一个可分辨名称数组作为结果。但所有其他属性都是可能的,只需将它们添加到 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();
    }