This post illustrates how can you retreive all user's emails that belongs to an Active Directory group in c# using the .NET framework 3.5.
Code snippets provides 3 classes that shows you how to obtain basic informations about users and group, quering a LDAP server:
- AdUser.cs is just a container class that rappresents a user with 3 basic properties: Distinguished Name, Display Name and Email
- AdUserCollection.js is just an AdUser collection
- ADSearcher.cs rappresents your Active Directory wrapper that retrieves your users based on LDAP queries
Use this classes and modify them to rappresents better your needs: right now the ADSearcher provides just methods to get Users that belongs to and Active Directory Group
ADUser class
public class AdUser
{
string _email;
string _name;
string _displayName;
public string Name
{
get { return _name; }
private set { _name = value.ToLower().Trim(); }
}
public string DisplayName
{
get { return _displayName; }
private set { _displayName = value.ToLower().Trim(); }
}
public string Email
{
get { return _email; }
private set { _email = value.ToLower().Trim(); }
}
public AdUser(string name, string displayName, string email)
{
Name = name;
DisplayName = displayName;
Email = email;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof(AdUser)) return false;
return Equals((AdUser)obj);
}
public bool Equals(AdUser other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other.Name, Name);
}
public override int GetHashCode()
{
unchecked
{
int result = (Name != null ? Name.GetHashCode() : 0);
return result;
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Name: "+ Name);
sb.AppendLine("DisplayName: " + DisplayName);
sb.AppendLine("Email: " + Email);
return sb.ToString();
}
}
ADUserCollection class
public class AdUserCollection : List<AdUser>
{
public string GetAllMails()
{
StringCollection sc = new StringCollection();
foreach (var item in this)
{
string email = item.Email.ToLower().Trim();
if (!String.IsNullOrEmpty(email) && !sc.Contains(email) )
{
sc.Add(email);
}
}
string toRet = string.Empty;
foreach (var item in sc)
{
toRet = string.Concat(toRet, ",", item );
}
toRet = toRet.Remove(0, 1);
return toRet;
}
new public void AddRange(AdUserCollection users)
{
foreach (var user in users)
{
if (!this.Contains(user))
{
this.Add(user);
}
}
}
}
ADSearcher class
public class ADSearcher
{
string _ldap = string.Empty;
public ADSearcher(string ServerLDAP)
{
_ldap = ServerLDAP;
}
public AdUserCollection GetUsersFromNeastedGroups
(StringCollection activeDirectoryGroups)
{
AdUserCollection users = new AdUserCollection();
foreach (var item in activeDirectoryGroups)
{
IEnumerable<AdUser> group = GetUsersFromAdGroup(item);
if (group != null)
users.AddRange(GetUsersFromAdGroup(item));
}
return users;
}
public IEnumerable<AdUser> GetUsersFromAdGroup
(string activeDirectoryGroup)
{
DirectoryEntry entry = new DirectoryEntry(_ldap);
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = String.Format("(&(objectCategory=group)(cn={0}))", activeDirectoryGroup);
search.PropertiesToLoad.Add("distinguishedName");
SearchResult searchResult = search.FindOne();
if (searchResult == null)
return null;
DirectoryEntry group = searchResult.GetDirectoryEntry();
Hashtable searchedGroups = new Hashtable();
return GetUsersInGroup(group.Properties["distinguishedName"].Value.ToString(),
searchedGroups);
}
HashSet<AdUser> GetUsersInGroup(string activeDirectoryGroup,
Hashtable searchedGroups)
{
HashSet<AdUser> groupMembers = new HashSet<AdUser>();
searchedGroups.Add(activeDirectoryGroup, activeDirectoryGroup);
// find all users in this group
DirectorySearcher ds = new DirectorySearcher(_ldap);
ds.Filter = String.Format("(&(memberOf={0})(objectClass=person))", activeDirectoryGroup);
ds.PropertiesToLoad.Add("sAMAccountName");
ds.PropertiesToLoad.Add("mail");
ds.PropertiesToLoad.Add("displayName");
//Add user to the list
foreach (SearchResult sr in ds.FindAll())
{
string name = sr.Properties["sAMAccountName"][0].ToString();
string email = string.Empty;
if (sr.Properties.Contains("mail"))
email = sr.Properties["mail"][0].ToString();
string displayname = string.Empty;
if (sr.Properties.Contains("displayName"))
displayname = sr.Properties["displayName"][0].ToString();
AdUser user = new AdUser(name, displayname, email);
if (groupMembers.Contains(user) == false)
{
groupMembers.Add(user);
}
}
List<string> nestedGroups = GetNestedGroups(activeDirectoryGroup);
foreach (string directoryGroup in nestedGroups)
{
if (searchedGroups.ContainsKey(directoryGroup) == false)
{
HashSet<AdUser> users = GetUsersInGroup(directoryGroup,
searchedGroups);
foreach (AdUser user in users)
{
if (groupMembers.Contains(user) == false)
{
groupMembers.Add(user);
}
}
}
}
return groupMembers;
}
private List<string> GetNestedGroups(string activeDirectoryGroup)
{
List<string> groupMembers = new List<string>();
DirectorySearcher ds = new DirectorySearcher(_ldap);
ds.Filter = String.Format("(&(memberOf={0})(objectClass=group))",
activeDirectoryGroup);
ds.PropertiesToLoad.Add("distinguishedName");
foreach (SearchResult sr in ds.FindAll())
{
groupMembers.Add(sr.Properties["distinguishedName"][0].ToString());
}
return groupMembers;
}
}
Once you have copied this classes into your project you could use the ADSearcher to get users' emails that belongs to an Active Directory Group:
ADSearcher searcher = new ADSearcher(ConfigurationManager.AppSettings["LdapServer"]);
AdUserCollection UsersInGroup = searcher.GetUsersFromMulitpleGroups(sc);
string UsersInGroupMails = UsersInGroup.GetAllMails();