Reputation: 1285
I am finding a reference to a security group to which I need to add user by using the following code:
string strActiveDirectoryPath = @"GC://domain.com";
DirectoryEntry directoryEntryRoot = new DirectoryEntry(strActiveDirectoryPath);
using (DirectorySearcher searcher = new DirectorySearcher(directoryEntryRoot))
{
searcher.PageSize = 1000;
searcher.Filter = "(&(objectClass=group)(cn=*SGNAME*))";
//searcher.SearchScope = SearchScope.Subtree;
SearchResult securityGroup = searcher.FindOne();
}
The above code sometimes throws an exception saying
Search resulted in too many records
Is my logic of fetching the security group correct?
Then I get reference to the user and try to add it to the security group:
searcher.Filter = "(SAMAccountName=" + UserAlias + ")";
searcher.PropertiesToLoad.Add("givenname");
searcher.PropertiesToLoad.Add("displayName");
SearchResult userALias = searcher.FindOne();
DirectoryEntry ent = new DirectoryEntry(securityGroup.Path);
string domainString = "GC://domain.com/";
int Start = domainString.Length;
string member = userALias.Path.Substring(domainString.Length);
ent.Properties["member"].Add(member);
// ent.Invoke("Add", new object[] { s });
ent.CommitChanges();
ent.Close();
I have created an instance of DirectoryEntry
and provided a path of the security group that I have found.
What should be provided to DirectoryEntry
?
CommitChanges
fails with exception:
The server is unwilling to process the request.
Upvotes: 0
Views: 2224
Reputation: 41008
I see a couple issue. First:
searcher.Filter = "(&(objectClass=group)(cn=*SGNAME*))";
SearchResult securityGroup = searcher.FindOne();
Because you're using wildcards, you're searching for any group with SGNAME
anywhere in the name. This has two problems:
cn
attribute is indexed, the index can't be used because you're using a wildcard at the beginning. It has to look at every group to try and find matches. This will slow down your search.DirectorySearcher.FindOne()
says:If more than one entry is found during the search, only the first entry is returned.
So you can't guarantee that the group returned is actually the one you want.
Why are you getting an exception then? I don't know. I would be curious to see the full exception details. There will probably be a hex number in there.
But I don't think that really matters. All of this would be solved by just matching the name exactly:
searcher.Filter = "(&(objectClass=group)(cn=SGNAME))";
Adding a member to the group
My guess is that your member
variable isn't a proper distinguishedName
. Instead of trying to parse the DN out of the Path
, just ask for the distinguishedName
in the search results. For example:
searcher.Filter = "(SAMAccountName=" + UserAlias + ")";
searcher.PropertiesToLoad.Add("distinguishedName");
SearchResult userALias = searcher.FindOne();
DirectoryEntry ent = securityGroup.GetDirectoryEntry();
string member = (string) userALias.Properties["distinguishedName"][0];
ent.Properties["member"].Add(member);
ent.CommitChanges();
ent.Close();
Update: You also cannot update via the Global Catalog. You must use LDAP://
:
string strActiveDirectoryPath = "LDAP://domain.com";
Or, if you really do need to search the GC (if you have multiple domains in your forest) then you'll have to switch to LDAP when you create your DirectoryEntry
for the group.
DirectoryEntry ent = new DirectoryEntry(securityGroup.Path.Replace("GC://", "LDAP://"));
Upvotes: 2