Reputation: 2073
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]);
}
}
}
Upvotes: 2
Views: 3426
Reputation: 3819
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.
Upvotes: 2