55

I am writing the following methods to add and remove users from active directory in C#.

void AddUserToGroup(string userId, string groupName);
void RemoveUserFromGroup(string userId, string groupName);

How best to implement these methods?

Here is some code from CodeProject. I can't see where the AD server is specified in these examples though? (is it implicitly supplied by the .NET framework when using the LDAP protocol?). Are these examples worth following?

public void AddToGroup(string userDn, string groupDn)
{
    try
    {
        DirectoryEntry dirEntry = new DirectoryEntry("LDAP://" + groupDn);
        dirEntry.Properties["member"].Add(userDn);
        dirEntry.CommitChanges();
        dirEntry.Close();
    }
    catch (System.DirectoryServices.DirectoryServicesCOMException E)
    {
        //doSomething with E.Message.ToString();

    }
}


public void RemoveUserFromGroup(string userDn, string groupDn)
{
    try
    {
        DirectoryEntry dirEntry = new DirectoryEntry("LDAP://" + groupDn);
        dirEntry.Properties["member"].Remove(userDn);
        dirEntry.CommitChanges();
        dirEntry.Close();
    }
    catch (System.DirectoryServices.DirectoryServicesCOMException E)
    {
        //doSomething with E.Message.ToString();

    }
}

4 Answers 4

102

Ugh. LDAP. If you're using the .Net Framework 3.5 or above, I highly recommend using the System.DirectoryServices.AccountManagement namespace. That makes things so much easier.

public void AddUserToGroup(string userId, string groupName) 
{ 
    try 
    { 
        using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "COMPANY"))
        {
            GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, groupName);
            group.Members.Add(pc, IdentityType.UserPrincipalName, userId);
            group.Save();
        }
    } 
    catch (System.DirectoryServices.DirectoryServicesCOMException E) 
    { 
        //doSomething with E.Message.ToString(); 

    } 
} 

public void RemoveUserFromGroup(string userId, string groupName)
{   
    try 
    { 
        using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "COMPANY"))
        {
            GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, groupName);
            group.Members.Remove(pc, IdentityType.UserPrincipalName, userId);
            group.Save();
        }
    } 
    catch (System.DirectoryServices.DirectoryServicesCOMException E) 
    { 
        //doSomething with E.Message.ToString(); 

    }
}
Sign up to request clarification or add additional context in comments.

16 Comments

System.DirectorServices.AccountManagement is only available in >= 3.5, rather than 3.0
Below code worked for me group.Members.Remove(UserPrincipal.FindByIdentity(pc, userId)); instead of "group.Members.Remove(pc, IdentityType.UserPrincipalName, userId);" . Note: my user id is just "USERNAME" without appending with domain name
Had a similar issue to the described above. I had to change the line that removes the user from the group from IdentityType.UserPrincipalName to IdentityType.SAMAccountName
What is userId ?
I know it was said in the above comments, but it wasn't clarified. If you send in DOMAIN\someUserId as your user, that's when you have to change it to IdentityType.SamAccountName, instead of UserPrincipalName. The latter will give you an exception: No principal matching the specified parameters was found. But note, too, it will also give you an exception with SamAccountName, if the user is already in the group.
|
5

The server is part of the groupDn variable value. For example:

LDAP://myServer/CN=MyGroup,CN=Groups,CN=MyContainer,DN=mydomain.com

The whole thing is the LDAP path for the group. The first part (myServer) is the server name.

The part after the server name (e.g. CN=...) is the DN (distinguished name) of the group.

2 Comments

The only thing I would say is that in a good AD setup, you should not have to specify the server. The .NET AD/low level AD calls should resolve the nearest available server for you. But this is more AD/domain setup and not so much code. If your AD setup is solid, you should be able to exclude the server (e.g. LDAP://CN=MyGroup,CN=Groups,CN=MyContainer,DN=mydomain.com)
Sorry didn't really answer your questions. yes, the examples do seem clean. If you are still unsure, I highly recommend the .NET Developer's Guide to Directory Services Programming (amazon.com/gp/product/0321350170)
2

When deleting a member in public void RemoveUserFromGroup(string userDn, string groupDn)

dirEntry.Properties["member"].Remove(userDn) does not work for me.

dirEntry.Properties["member"].RemoveAt(dn.IndexOf(dn)) works.

3 Comments

What is the dn variable?
@fripp13, in the context of an Active Directory, dn almost always means DistinguishedName.
@Andy The RemoveAt(int) method requires an index. If you call userDn.IndexOf(userDn), the method will always return 0 (Example: "TEST".IndexOf("TEST") will return 0). The 2nd proposal will always remove the first entry in the list.
1

You can put the LDAP server in the path argument to DirectoryEntry, so "LDAP://" + ldapServer + ldapQuery.

Use the DirectoryEntry(String path, String userId, String password) if you need to authenticate

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.