从活动目录中检索数据会得到不完整的列表

时间:2012-06-17 07:48:22

标签: c# .net active-directory

我是stackoverflow的新成员,虽然我经常关注这个:) 我的代码连接到活动目录以获取功能组的成员,在列表中实际上只有1690个奇怪成员中的1490个成员。我在Stackoverflow和Internet上搜索了很多,但我还没有找到答案,为什么代码会导致列表不完整。可以,有人请给我任何指示。谢谢:))

以下是连接到Active Directory以检索数据的代码:

    public static DataTable GetAdUsers(string configSection)
    {

        DataRow dr; 
        Hashtable ADGroups = (Hashtable)ConfigurationManager.GetSection(configSection);
        string adGroup;
        string adGroupDesc;
        string sApplication;
        string sLast_Login;
        string sAccount_owner;
        string sPath;

        DataTable dt = new DataTable();

        sApplication = "Application";
        dt.Columns.Add(sApplication);

        dt.Columns.Add("Profile", Type.GetType("System.String"));
        dt.Columns.Add("Account Name", Type.GetType("System.String"));

        sLast_Login = "Last Login";
        dt.Columns.Add(sLast_Login);

        sAccount_owner = "Account Owner";
        dt.Columns.Add(sAccount_owner);

        sPath = "Path";
        dt.Columns.Add(sPath);

        string domainName = "myDomain";

        PrincipalContext pcRoot = new PrincipalContext(ContextType.Domain, domainName);
        IDictionaryEnumerator adGroupEnumerator = ADGroups.GetEnumerator();

        while (adGroupEnumerator.MoveNext())
        {
            adGroup = adGroupEnumerator.Key.ToString();
            adGroupDesc = adGroupEnumerator.Value.ToString();

            GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcRoot, IdentityType.SamAccountName, adGroup); 
            System.DirectoryServices.DirectoryEntry de = (System.DirectoryServices.DirectoryEntry)grp.GetUnderlyingObject();
            foreach (string sDN in de.Properties["member"])
            {
                System.DirectoryServices.DirectoryEntry deMember = new System.DirectoryServices.DirectoryEntry("LDAP://" + sDN.ToString());
                try
                {
                    dr = dt.NewRow();

                    string output1;
                    string subStringE1 = "DC=";
                    int length1 = de.Path.ToString().Length;
                    int length0 = de.Path.ToString().IndexOf(subStringE1);
                    string str1 = de.Path.ToString().Substring(length0, length1 - length0);
                    string subStringE2 = ",DC";
                    int length2 = str1.ToString().IndexOf(subStringE2);
                    output1 = str1.ToString().Substring(3, length2 - 3);

                    dr["Application"] = "Application";
                    dr["Profile"] = adGroupDesc;

                    string AccountName = deMember.Properties["samAccountName"].Value.ToString();

                    dr["Account Name"] = deMember.Properties["samAccountName"].Value.ToString();
                    dr["Last Login"] = "";
                    dr["Account Owner"] = deMember.Properties["givenName"].Value.ToString() + @"-" + deMember.Properties["sn"].Value.ToString();

                    string Path = output1 + @"\" + adGroup + @"\" + deMember.Properties["samAccountName"].Value.ToString();

                    Console.WriteLine(Path);
                    dr["Path"] = output1 + @"\" + adGroup + @"\" + deMember.Properties["samAccountName"].Value.ToString();

                    dt.Rows.Add(dr);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error occured for user name" + sDN + "\n" + ex.Message);
                }
            }
        }
        return dt;
    }
}

3 个答案:

答案 0 :(得分:0)

由于SizeLimit的默认限制,您可能只能获得1,490个左右的对象。要解决这个问题,您需要在结果中“翻页”。

只需使用Enumerating Members in a Large Group 中引用的代码。

答案 1 :(得分:0)

如果返回的结果集可能包含超过1000个项目,则必须使用分页搜索。在没有分页的情况下执行的Active Directory搜索仅限于返回前1000条记录中的最大值。通过分页搜索,结果集呈现为单独的页面,每个页面包含预定数量的结果条目。使用此类搜索,将返回结果条目的新页面,直到达到结果集的末尾。

默认情况下,响应查询请求的服务器在返回数据之前完全计算结果集。在大型结果集中,这需要获取结果集时的服务器内存,以及返回大结果时的网络带宽。设置页面大小允许服务器在构建页面时以页面形式发送数据。然后,客户端缓存此数据并向应用程序级代码提供游标。

通过定义服务器在通过网络将数据返回给客户端之前计算的行数来设置分页。

答案 2 :(得分:0)

通过研究和尝试我的运气找到了答案。 使用目录条目是一个问题,并没有使用页面搜索,虽然我也尝试过。

工作代码如下:

GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcRoot, adGroup); //fglbcmdolpctx
                if (grp != null)
                {
                    foreach (Principal p in grp.GetMembers(true))
                    {
                        try
                        {
                            dr = dt.NewRow();
                            dr["Application"] = "Commodities OpenLink";
                            dr["Profile"] = adGroupDesc;
                            string AccountName = p.SamAccountName.ToString().ToLower();
                            dr["Account Name"] = AccountName;
                            dr["Last Login"] = "";
                            string sLastName, sFirstName;
                            int iLastNameIndex0, iLastNameIndex1, iFirstNameIndex0, iFirstNameIndex1;
                            int lengthofString = p.Name.ToString().Length;
                            iLastNameIndex1 = p.Name.ToString().IndexOf(",");


                            if (iLastNameIndex1 == -1)
                            {
                                sLastName = "";
                            }
                            else
                            {
                                sLastName = p.Name.ToString().Substring(0, iLastNameIndex1);
                            }

                            iFirstNameIndex0 = p.Name.ToString().IndexOf(",");
                            iFirstNameIndex1 = p.Name.ToString().IndexOf(":");
                            if (iFirstNameIndex0 == -1 || iFirstNameIndex1 == -1)
                            {
                                sFirstName = p.Name.ToString();
                                sLastName = "";
                            }
                            else
                            {
                                sFirstName = p.Name.ToString().Substring(iFirstNameIndex0 + 1, iFirstNameIndex1 - iFirstNameIndex0 - 1);
                            }

                            sAccount_owner = sLastName + @"-" + sFirstName;
                            dr["Account Owner"] = sAccount_owner;

                            string sPath_Domain_Part;
                            string sFirstIndexofExtraction = "DC=";
                            int ilength_String = p.DistinguishedName.ToString().Length;
                            int iLenght_ExtractionPoint1 = p.DistinguishedName.ToString().IndexOf(sFirstIndexofExtraction);
                            string str1 = p.DistinguishedName.ToString().Substring(iLenght_ExtractionPoint1, ilength_String - iLenght_ExtractionPoint1);

                            string subStringE2 = ",DC";
                            int iLenght_ExtractionPoint2 = str1.IndexOf(subStringE2);
                            sPath_Domain_Part = str1.Substring(3, iLenght_ExtractionPoint2 - 3);
                            string sPath1 = sPath_Domain_Part + @"\" + adGroup + @"\" + p.SamAccountName.ToString();
                            dr["Path"] = sPath_Domain_Part + @"\" + adGroup + @"\" + p.SamAccountName.ToString();
                            dt.Rows.Add(dr);
                        }

                        catch (Exception ex)
                        {
                            Global.logfile.WriteLine("Error occured for user name" + adGroup + p.SamAccountName + "\n" + ex.Message);
                        }
                    }
                }