Adding and removing users from Active Directory groups in .NET

89,968

Solution 1

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(); 

    }
}

Solution 2

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.

Solution 3

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.

Solution 4

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

Share:
89,968
Ben Aston
Author by

Ben Aston

Updated on October 06, 2020

Comments

  • Ben Aston
    Ben Aston over 3 years

    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();
    
        }
    }
    
  • Mike Marshall
    Mike Marshall over 14 years
    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)
  • Mike Marshall
    Mike Marshall over 14 years
    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)
  • regex
    regex over 11 years
    System.DirectorServices.AccountManagement is only available in >= 3.5, rather than 3.0
  • Ram
    Ram over 11 years
    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
  • Jacob Proffitt
    Jacob Proffitt over 11 years
    Yeah, that overload works, too, it's just an extra call into the LDAP service to get the user identity before sending the remove call. Frankly, it's possible that they're equivalent in function as the API probably calls into the LDAP for the identity based on user name before doing the remove, too.
  • Ju66ernaut
    Ju66ernaut almost 9 years
    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
  • Kiquenet
    Kiquenet over 8 years
    What is userId ?
  • forcewill
    forcewill over 7 years
    The only issue with the System.DirectorServices.AccountManagement is that if the machine is not in the domain it gets me an error >.<
  • vapcguy
    vapcguy over 7 years
    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.
  • vapcguy
    vapcguy over 7 years
    On the removal from the group - if the user was never in the group to begin with, it doesn't provide an exception - it will just go through the .Save() operation, regardless. You have to check if the UserPrincipal object for the user .IsMemberOf(group), to discover this. Submitted an edit. userId should be in DOMAIN\username form to send to UserPrincipal.FindByIdentity(pc, userId);, however, which would require SamAccountName in the IdentityType.
  • fripp13
    fripp13 about 7 years
    What is the dn variable?
  • codeMonkey
    codeMonkey about 7 years
    @Rama I would post that as a separate answer--that helped me a ton!
  • Aravin
    Aravin over 6 years
    What does company means in that both method?
  • Mathias Maes
    Mathias Maes about 6 years
    @fripp13, in the context of an Active Directory, dn almost always means DistinguishedName.
  • vbhosale
    vbhosale over 3 years
    @vapcguy Getting this error- No principal matching the specified parameters was found.'
  • vapcguy
    vapcguy over 3 years
    @vbhosale Read my comments above. I specified why that happens. Use IdentityType.SamAccountName, instead, but then you have to make sure they are not in the group, to begin with, too. Do you know they are in the group, but are not getting found? Then you can look for them by their SSID.