2012-06-17 5 views
0

Я новичок в stackoverflow как член, хотя я многому следую за ним :) Мой код, который подключается к активной директории для получения членов функциональной группы, дает мне всего 1490 нечетных членов из 1680 нечетных членов, фактически входящих в список. Я много искал в Stackoverflow и в Интернете, но я не нашел ответа на вопрос, почему код приведет к неполному списку. Может, кто-нибудь, пожалуйста, дайте мне какие-нибудь указания на это. Спасибо :)Извлечение данных из активного каталога дает неполный список

Вот код, который подключается к 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; 
    } 
} 
+0

Так вы используете .NET 3.5 'PrincipalContext' и все - тогда ** ** почему вы переключение обратно в старом стиле .NET 2.0 'DirectoryEntry', если у вас есть имя участника? Не имеет никакого смысла и делает вещи намного более громоздкими! У вас уже есть 'GroupPrincipal grp' - почему вы не используете' .GetMembers() 'call для получения членов группы? Было бы намного проще! ** –

+0

Привет, Марк, у вас есть какие-то указатели/ссылки на них. Большинство результатов seacrh, которые я получил, были на .NET 2.0. Также ссылка Afifi в Msdn также находится на .NET 2.0. – Ashutosh

+0

См. Статью журнала MSDN: [Управление принципами безопасности в платформе .NET Framework 3.5] (http://msdn.microsoft.com/en-us/magazine/cc135979.aspx) –

ответ

0

Из-за лимита по умолчанию SizeLimit, вы, вероятно, только получать вокруг 1490 объектов или около того. Чтобы исправить это, вам нужно выполнить «страницу» по результатам.

Просто используйте код, указанный по адресу: Enumerating Members in a Large Group.

+0

Большое спасибо Afifi :) Просто работаю над тем же. Ссылка очень полезна – Ashutosh

+0

Ссылка очень полезна, но groupMember.FindOne() приводит к неизвестной ошибке. – Ashutosh

+0

Но когда я использую код, указанный в ссылке, я получаю сообщение об ошибке «Ошибка произошла для имени пользователя member; range = 0- *» – Ashutosh

0

Если существует вероятность того, что результирующий набор, который будет возвращен, будет содержать более 1000 предметов, вы должны использовать поисковый запрос. Поиски Active Directory, выполняемые без пейджинга, ограничены возвратом максимум первых 1000 записей. С помощью поискового вызова результирующий набор представляется как отдельные страницы, каждый из которых содержит заданное количество записей результатов. При таком типе поиска новые страницы записей результатов возвращаются до тех пор, пока не будет достигнут конец результирующего набора.

По умолчанию сервер, который отвечает на запрос запроса, полностью вычисляет набор результатов перед возвратом данных. В большом результирующем наборе для этого требуется память сервера при получении набора результатов и пропускная способность сети при возврате большого результата. Настройка размера страницы позволяет серверу отправлять данные на страницах по мере создания страниц. Затем клиент кэширует эти данные и предоставляет курсор кода уровня приложения.

Пейджинг задается путем определения количества строк, которое сервер рассчитывает до того, как данные будут переданы по сети клиенту.

+0

Спасибо Jakub, работая над идеями и ссылками вашего и Afifi :) – Ashutosh

0

Нашел ответ, исследуя и пробуя мою удачу. Использование Directory Entry было проблемой и не использовало поиск страниц, хотя я пробовал то же самое.

Рабочий код, как показано ниже:

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); 
         } 
        } 
       } 
+0

Не забудьте отметить свой ответ как принятый – j0k

Смежные вопросы