Optimize AD search - get group members

落花浮王杯 提交于 2019-12-23 23:41:11

问题


Is it possible to query only those members of group, which is also group from AD?

Now I am using following code:

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

The problem is that my group has a big amount of users (more than 50 000), as a result the query works extremely long. Also, big amount of data is transferred.

How can I query only direct sub groups (not users) in a single request?

EDIT

I ended up with DirectorySearcher. Here is my completed code:

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]);
        }
    }
}

回答1:


I would suggest using the the lower level DirectoryServices.Protocols namespace instead of DirectoryServices.AccountManagement for something like this.

The problem I've had (along with many others) with the AccountManagement libraries is the lack of customization and configuration. That being said, this is how I search through Active Directory, making use of System.DirectoryServices.Protocols.SearchScope as well.

//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;

This is where DirectoryServices really starts to shine. You can easily define a filter to search by a particular group or subgroup. You could do something like this :

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;

This may not be exactly what you need, but as you can see, you'll have a lot more flexibility to change and modify the search criteria. I use this code to search massive domain structures, and it's almost instantaneous, even with large amounts of users and groups.



来源:https://stackoverflow.com/questions/17088833/optimize-ad-search-get-group-members

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!