2013-06-13 4 views
2

Можно ли запросить только тех членов группы, которые также являются группой из AD?Оптимизировать поиск в AD - получить членов группы

Теперь я использую следующий код:

var group = GroupPrincipal.FindByIdentity(ctx, identityType, domainGroup); 
if (null != group) 
{ 
    var subGroups = group.GetMembers().Where(g => g is GroupPrincipal).Select(g => g.Name); 
................ 
} 

Проблема заключается в том, что моя группа имеет большое количество пользователей (более 50 000), в результате запроса работает очень долго. Кроме того, переносится большой объем данных.

Как я могу запросить только прямые подгруппы (а не пользователи) в одном запросе?

EDIT

Я закончил с DirectorySearcher. Вот мой код завершения:

using (var searcher = new DirectorySearcher(string.Format("(&(objectCategory=group)(objectClass=group)(memberof={0}))", group.DistinguishedName), new[] { "cn" })) 
{ 
    searcher.PageSize = 10000; 
    var results = SafeFindAll(searcher); 

    foreach (SearchResult result in results) 
    { 
     for (int i = 0; i < result.Properties["cn"].Count; i++) 
     { 
      subGroups.Add((string)result.Properties["cn"][i]); 
     } 
    } 
} 
+0

Любопытно, какое увеличение производительности вы видите? – X3074861X

+0

@ X3074861X, производительность зависит от количества групп пользователей. Вышеуказанный запрос позволяет пропустить выбор пользователя, потому что я запрашиваю только группы, в результате для некоторых групп производительность сильно возрастает. – Kai

ответ

2

Я предложил бы использовать нижний уровень DirectoryServices.Protocols имен вместо DirectoryServices.AccountManagement что-то вроде этого.

Проблема, с которой я столкнулся (наряду со многими другими) с библиотеками AccountManagement, заключается в отсутствии настройки и конфигурации. Это, как говорится, так я просматриваю через Active Directory, используя также System.DirectoryServices.Protocols.SearchScope.

//Define the connection 
var ldapidentifier = new LdapDirectoryIdentifier(ServerName, port); 
var ldapconn = new LdapConnection(ldapidentifier, credentials); 

//Set some session options (important if the server has a self signed cert or is transferring over SSL on Port 636) 
ldapconn.SessionOptions.VerifyServerCertificate += delegate { return true; }; 
ldapconn.SessionOptions.SecureSocketLayer = true; 

//Set the auth type, I'm doing this from a config file, you'll probably want either Simple or Negotatie depending on the way your directory is configured. 
ldapconn.AuthType = config.LdapAuth.LdapAuthType; 

Здесь DirectoryServices действительно начинает светиться. Вы можете легко определить фильтр для поиска по определенной группе или подгруппе. Вы могли бы сделать что-то вроде этого:

string ldapFilter = "(&(objectCategory=person)(objectclass=user)(memberOf=CN=All Europe,OU=Global,dc=company,dc=com)"; 

//Create the search request with the domain, filter, and SearchScope. You'll most likely want Subtree here, but you could possibly use Base as well. 
var getUserRequest = new SearchRequest(Domain, ldapFilter, SearchScope.Subtree)           

//This is crucial in getting the request speed you want. 
//Setting the DomainScope will suppress any refferal creation during the search 
var SearchControl = new SearchOptionsControl(SearchOption.DomainScope); 
getUserRequest.Controls.Add(SearchControl); 

//Now, send the request, and get your array of Entry's back 
var Response = (SearchResponse)ldapconn.SendRequest(getUserRequest); 

SearchResultEntryCollection Users = Response.Entries; 

Это не может быть точно , что вам нужно, но как вы можете видеть, вы будете иметь гораздо больше гибкости, чтобы изменять и модифицировать критерии поиска. Я использую этот код для поиска массивных доменных структур, и это почти мгновенно, даже с большим количеством пользователей и групп.

+0

Спасибо за предложение. – Kai

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