Reputation: 25521
I have a user query that can't be done at an OU level. I am trying to only return users where they are a member of a group (I need to filter by the group string value, not the actual group object). Here is what it currently looks like:
using (var entry = new DirectoryEntry("LDAP://foo.net/DC=appName,DC=domainName,DC=com", Username, Password)) {
using (var searcher = new DirectorySearcher()) {
searcher.Filter = "(&(objectClass=user))";
searcher.SearchRoot = entry;
searcher.PropertiesToLoad.Add("memberOf");
foreach (SearchResult sr in searcher.FindAll()) {
var member = GetSearchResultProperty(sr, "memberOf");
}
}
}
This query goes across multiple OU's where there are different user and group containers.
Is there a way I can filter on the memberOf
property when I execute my query (without specifying any sort of OU)?
Upvotes: 1
Views: 7157
Reputation: 3819
You need to include the full distinguished name of the group in your search filter, as the memberOf property will contain that value.
searcher.Filter = "(&(objectClass=user)(memberOf=CN=myGroup,CN=groups,OU=theOU,DC=appName,DC=domainName,DC=com))";
EDIT :
My apologies, as I misread the question. Without including an OU, the only other way of doing this is taking the opposite approach, and locating the group object first :
searcher.Filter = "(&(objectClass=group)(name=Your Group Name)"
Then iterate through the DirectoryEntry
using it's properties :
foreach(object dn in group.Properties["member"] )
{
string DistinguishedName = dn.ToString();
}
If you're retrieving more than 1,000+ users though, you'll need to take a more segmented approach, which is detailed in this article.
Upvotes: 1
Reputation: 25521
It looks like what I am trying to do isn't possible at the time of query execution because the memberOf
property needs to be a full path to a group. In my case, I don't actually care about the group object, but, rather the group name (each OU will have different groups, but, could have the same group name). I had to take a different approach to solve this which could have performance implications later on. Just in case someone else finds this question looking for an answer, here is how I am solving it as of now:
using (var entry = new DirectoryEntry("LDAP://foo.net/DC=appName,DC=domainName,DC=com", Username, Password)) {
using (var searcher = new DirectorySearcher()) {
searcher.Filter = "(&(objectClass=user))";
searcher.SearchRoot = entry;
searcher.PageSize = 5000;
searcher.PropertiesToLoad.Add(DirectoryConstants.AD_PROPERTY_MEMBER_OF);
searcher.PropertiesToLoad.Add(DirectoryConstants.AD_PROPERTY_DISPLAY_NAME);
foreach (SearchResult sr in searcher.FindAll()) {
//The memberOf property will be a string array if the user is in multiple groups.
string[] memberOf = GetSearchResultProperties(sr, DirectoryConstants.AD_PROPERTY_MEMBER_OF);
//Check if the user is in the group by analyzing the string.
var group = memberOf.FirstOrDefault(m => m.StartsWith(string.Format("CN={0},", groupName)));
if (group != null) {
//The user is in the group!
}
}
}
}
Upvotes: 1
Reputation: 310860
Just add another term to the filter:
searcher.Filter = "(&(objectClass=user)(memberOf=myGroup))";
Upvotes: 1