Tuesday, May 30, 2006

Adding Members to the Active Directory Group using .NET

Recently on my project we had a requirement to add members to an Active Directory group.Now after going through every possible place on help and google, i finally found the holy grail and thought to share some findings and code bits.
We had to add computer names(implementation is same for user_name also) to the active directory group.
Some important points to be kept in mind while working active directory groups:
1. Get the Group name. Make sure you are an admin on that group (or use impersonation), if you want to make changes.Imp: You also need domain name to which the group belongs. just a group name will not do.
2. We have to find the exact path on which this group exist.
3. After finding the exact location of the group, we can add the members to the group.
4. Only exisitng members in the active directory can be added to an active directory group. Members can belong to any domain in the organization. Only important thing is that member does exist in the active directory. For this we also need the path of the member where it exists in the Active Directory.

Lets just take a look at the path and try to understand:1. CN=machineName,OU=Servers,OU=Computers,OU=Unit1,DC=dc1,DC=dc2,DC=com
this is my machine name path in the active directory.
2. LDAP://domains/CN=groupName,OU=Groups,OU=Users,OU=Unit1,DC=dc1,DC=dc2,DC=com
this is my group name path in the active directory.
Now you can see the difference between the two. Lets try and think how they are logically placed

O = Organization
|_____OU = Servers
|_____ OU = Computers
|______ OU = Unit1
|_____ DC = dc1.dc2.com

O = Organization
|_______ OU = Groups
|_____ OU = Users
|______ OU = Unit1
|_____ DC = dc1.dc2.com

CN is the class name.

.NET with Active Directory

Namespace:using System.DirectoryServices

Get Group Path name. Also if you know the domain\, you can find the path for that also.

/// Method is used to get the group path.
/// param name="groupName" Domain\GroupName
/// returns LDAP://domain/CN= groupName,OU=Groups,OU=Users,OU=Unit1,DC=dc1,DC=dc2,DC=com

private string GetLdapPath(string domainGroupName)
{
try
{
//separate the domain name and the groupname
string domain = domainGroupName.Substring(0, globalGroupName.IndexOf(@"\"));
string groupName = domainGroupName.Substring(globalGroupName.IndexOf(@"\")+1);

DirectoryEntry oEntry = new DirectoryEntry();
oEntry.Path = "LDAP://" + domain;

//search the directory on the specified path.
DirectorySearcher oSearcher = new DirectorySearcher(oEntry);

//this is a default format for searching a group name.. .dont change "SAMAccountName"
oSearcher.Filter = String.Format("(SAMAccountName={0})",groupName );
oSearcher.PropertiesToLoad.Add("cn");

SearchResult oResult = oSearcher.FindOne();

if(oResult == null)
{
throw new Exception("Group: " +groupName+ " not found in the domain: "+domain);
}
else
{
return oResult.Path;
}
}
catch(Exception ex){
}

Adding member to the active directory group. In the code e.g. i am adding a machine name. But you can also add an already exisitng user name. Whoever be the member, you need the Ldap path for that. Use the same method GetLdapPath to get the user_name path or machine_name path. Make sure you have domain name for them.

/// Method is used to add members to the global group.
/// param name="domainGroupName"
/// param name="machineName"
public void AddMembersToGroup(string domainGroupName, string machineName)
{
//get path for group name and machine name.
string groupDirectoryPath = GetLdapPath(domainGroupName);
string machineLdapPath = GetLdapPath(machineName)

//create the instance of the Directory Entry on the path found.
DirectoryEntry oGroupEntry = new DirectoryEntry();
oGroupEntry.Path = groupDirectoryPath;

try
{
//add a new member
oGroupEntry.Properties["member"].Add(machineLdapPath);
//commit the changes to reflect in the directory.
oGroupEntry.CommitChanges();
}
catch(Exception ex){}
}

Delete memebers from the Group.

/// Method is used to delate all the memebrs from the global group.
/// param name="groupName"
public void DeleteAllMembers(string groupName)
{
string groupDirectoryPath = GetLdapPath(groupName);

DirectoryEntry oEntry = new DirectoryEntry();
oEntry.Path = groupDirectoryPath;

try
{
//clear all the members.
oEntry.Properties["member"].Clear();
//commit changes.
oEntry.CommitChanges();
}
catch(Exception ex){}
}

Read the members from the Active Directory Group. The method below will write on the console all the members in the group.
This is really if good if you application authorization and authentication is based on the role of members of the active directory as it saves the time of creation of user database for your application.

/// Method is used to loop through the group and find members.
/// param name="groupName"
public void SearchGlobalGroup(string groupName)
{

//instance of the directory entyry
DirectoryEntry oEntry = new DirectoryEntry();
oEntry.Path = GetLdapPath(groupName);
//impersonate if the security context the app is running does not have permission on the Directory.
oEntry.Username = "user_name";
oEntry.Password = "pswd";
oEntry.AuthenticationType = AuthenticationTypes.Secure;


try
{
SearchResult result;
DirectorySearcher oSearcher = new DirectorySearcher(oEntry);
oSearcher.PropertiesToLoad.Add("member");
result = oSearcher.FindOne();

if (result != null)
{
for (int counter = 0; counter < result.Properties["member"].Count; counter++)
{
string user = (string)result.Properties["member"][counter];
Console.WriteLine(user);
}
}


}
catch(Exception ex){}
}

For more info check these links:
http://www.csharphelp.com/archives3/archive582.html
http://www.ondotnet.com/pub/a/dotnet/2003/08/04/activedir.html
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdirectoryservices.asp

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home