Adding Existing User to Existing AD Group

I read this thread the other day: and combined the suggestions into code like this:


/// Method to add a user to a group

public static void AddUserToGroup(DirectoryEntry de, DirectoryEntry deUser, string GroupName){
    DirectorySearcher deSearch 
= new DirectorySearcher();
deSearch.SearchRoot de;
deSearch.Filter "(&(objectClass=group) (cn=" + GroupName +"))"
SearchResultCollection results deSearch.FindAll();

isGroupMember = false;

    if (results.Count > 0)
        DirectoryEntry group = results[0].GetDirectoryEntry();
        isGroupMember = (bool)group.Invoke("IsMember", new object[] { deUser.Path });
        if (!isGroupMember){
            group.Invoke("Add", new object[] {deUser.Path.ToString()});


But I'm not sure about the parameters to this function because there are 5 different overloads to instantiate the DirectoryEntry object.

How would I use the function to add a user to an AD group?



0 David55 8/7/2008 2:00:14 PM

First, (and no offence intended to anyone here) but you might be better posting questions like this to microsoft.public.adsi.general via Google Groups - that group is dedicated to Active Directory programming and there are some really good guys there who've given me loads of help.

Second, if you're going to be doing a lot of this stuff, I recommend "The .NET Developer's Guide to Directory Services Programming" by Joe Kaplan (who inhabits microsoft.public.adsi.general a lot) and Ryan Dunn.  It's very accessible.

Third, which version of .NET are you using - difference versions have different options? If you can use .NET 3.5, read up on System.DirectoryServices.AccountManagement namespace - they do things differently there (and probably easier).

Fourth, System.DirectoryServices is a wrapper around ADSI - sometimes you'll have to understand how ADSI works to understand what S.DS objects are doing.

Fifith, your specific problem:

DirectorySearcher defaults to searching the whole of the current domain (i.e. the one the user is logged into), so, if you want to search the whole domain, you can do away with this line:

    deSearch.SearchRoot de;

and this parameter of the method.

But you'll still need an instance of DirectoryEntry for your user.   Of the constructors, this one: DirectoryEntry(string path) is probably the best one to start with.  The path is an ADsPath - I'll leave you to look up the specifics but the short version is that it's made up of a prefix and a path.  The prefix can be LDAP:// (exactly like that, in caps) or WinNT:// (but avoid this as it'll get you into trouble whenever you want to do anything clever).  The path is the distinguishedName of the object in the directory.  e.g. "CN=user1,OU=HeadOfficeUsers,DC=domain,DC=com", so together, you get:

DirectoryEntry fred = new DirectoryEntry("LDAP://CN=user1,OU=HeadOfficeUsers,DC=domain,DC=com");

not that ADSI doesn't get the object at this point, so you won't see any exceptions until you try to do something with it.

If you don't know the distinguishedName, open up the MMC ADSIEdit and find your object.  Look at it's properties and you'll see distinguishedName amongst them.

Note, also, that DirectoryEntry, DirectorySearcher and SearchResultsCollection all implement IDisposable.  To save leaving stuff hanging around and gobbling up memory, you should use using wrappers round them.  This will take care of calling Dispose automatically, saving you having to remember.


using (DirectoryEntry fred = new DirectoryEntry("LDAP://CN=user1,OU=HeadOfficeUsers,DC=domain,DC=com"))


    //your code that uses the fred object



Anyway, to use this method:

  • set de to be a DirectoryEntry which points, to an OU which contains your group (or one higher up in the hierarchy),
  • make deUser a DirectoryEntry which point to the user account
  • GroupName is just the name of the group (not its distinguishedName).
0 ssg31415926 8/7/2008 2:35:41 PM

Thanks, ssg31415926, for your answer. I'm still hacking away at this. FWIW, I'm using .NET 2.0 and will need to accomplish adding a user, removing a user, and listing users in several groups. I will pursue the Google groups suggestion but am open to any more insights here.

0 David55 8/7/2008 7:42:18 PM

Okay, I'll try to dig out some code tomorrow.

0 ssg31415926 8/7/2008 8:22:23 PM

Ah, I think I have it working but the problem is that the user that IIS is running as doesn't have permissions to alter the group. I get a permission denied error, in fact, but I am able to return as true that I am a member of the group.

Is it possible to run the action as myself, since I have admin permissions on the group in question?

Some progress, maybe...

0 David55 8/7/2008 9:24:31 PM

There are two constructors for DirectoryEntry that allow you to pass credentials: 

public DirectoryEntry(
string path,
string username,
string password
0 ssg31415926 8/7/2008 9:38:28 PM

Thanks, ssg31415926, I think it will work now with the user supplied credentials.

When in production, the superuser will have to supply credentials to manage and list users of the application.

Thanks, again for all your help.




0 David55 8/8/2008 1:34:13 PM

Are you using SSL?  Ideally, you wouldn't want superuser creds to be passed in plain text across a network.

0 ssg31415926 8/8/2008 1:51:02 PM

Yes, the production server uses SSL, but not on my dev box.

0 David55 8/8/2008 2:00:38 PM

(Thread closed)