I checked this post already. But it doesn\'t answer my question. I want to get all the active directory groups in which a particular user is a member.
I\'ve written
You should use System.DirectoryServices.AccountManagement. It's much easier. Here is a nice code project article giving you an overview on all the classes in this DLL.
As you pointed out, your current approach doesn't find out the primary group. Actually, it's much worse than you thought. There are some more cases that it doesn't work, like the domain local group from another domain. You can check here for details. Here is how the code looks like if you switch to use System.DirectoryServices.AccountManagement. The following code can find the immediate groups this user assigned to, which includes the primary group.
UserPrincipal user = UserPrincipal.FindByIdentity(new PrincipalContext (ContextType.Domain, "mydomain.com"), IdentityType.SamAccountName, "username");
foreach (GroupPrincipal group in user.GetGroups())
{
Console.Out.WriteLine(group);
}
The following example is from the Code Project article, (Almost) Everything In Active Directory via C#:
// userDn is a Distinguished Name such as:
// "LDAP://CN=Joe Smith,OU=Sales,OU=domain,OU=com"
public ArrayList Groups(string userDn, bool recursive)
{
ArrayList groupMemberships = new ArrayList();
return AttributeValuesMultiString("memberOf", userDn,
groupMemberships, recursive);
}
public ArrayList AttributeValuesMultiString(string attributeName,
string objectDn, ArrayList valuesCollection, bool recursive)
{
DirectoryEntry ent = new DirectoryEntry(objectDn);
PropertyValueCollection ValueCollection = ent.Properties[attributeName];
IEnumerator en = ValueCollection.GetEnumerator();
while (en.MoveNext())
{
if (en.Current != null)
{
if (!valuesCollection.Contains(en.Current.ToString()))
{
valuesCollection.Add(en.Current.ToString());
if (recursive)
{
AttributeValuesMultiString(attributeName, "LDAP://" +
en.Current.ToString(), valuesCollection, true);
}
}
}
}
ent.Close();
ent.Dispose();
return valuesCollection;
}
Just call the Groups method with the Distinguished Name for the user, and pass in the bool flag to indicate if you want to include nested / child groups memberships in your resulting ArrayList:
ArrayList groups = Groups("LDAP://CN=Joe Smith,OU=Sales,OU=domain,OU=com", true);
foreach (string groupName in groups)
{
Console.WriteLine(groupName);
}
If you need to do any serious level of Active Directory programming in .NET I highly recommend bookmarking & reviewing the Code Project article I mentioned above.
If you have a LDAP connection with a username and password to connect to Active Directory, here is the code I used to connect properly:
using System.DirectoryServices.AccountManagement;
// ...
// Connection information
var connectionString = "LDAP://domain.com/DC=domain,DC=com";
var connectionUsername = "your_ad_username";
var connectionPassword = "your_ad_password";
// Get groups for this user
var username = "myusername";
// Split the LDAP Uri
var uri = new Uri(connectionString);
var host = uri.Host;
var container = uri.Segments.Count() >=1 ? uri.Segments[1] : "";
// Create context to connect to AD
var princContext = new PrincipalContext(ContextType.Domain, host, container, connectionUsername, connectionPassword);
// Get User
UserPrincipal user = UserPrincipal.FindByIdentity(princContext, IdentityType.SamAccountName, username);
// Browse user's groups
foreach (GroupPrincipal group in user.GetGroups())
{
Console.Out.WriteLine(group.Name);
}
Just query the "memberOf" property and iterate though the return, example:
search.PropertiesToLoad.Add("memberOf");
StringBuilder groupNames = new StringBuilder(); //stuff them in | delimited
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
String dn;
int equalsIndex, commaIndex;
for (int propertyCounter = 0; propertyCounter < propertyCount;
propertyCounter++)
{
dn = (String)result.Properties["memberOf"][propertyCounter];
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if (-1 == equalsIndex)
{
return null;
}
groupNames.Append(dn.Substring((equalsIndex + 1),
(commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
return groupNames.ToString();
This just stuffs the group names into the groupNames string, pipe delimited, but when you spin through you can do whatever you want with them