There are two known problems using the "Groups" property in DirectoryEntry:
- it will not show you the "default group" in which the user is located (usually "users").
- he will not show you membership in nested groups
So, if a user is a member of group A, and this group, in turn, is a member of group B, then on Windows this means that the user is also a member of group B. However, DirectoryEntry will not show you this nested membership in the group.
These are the two limitations that I know for direct Active Directory (without Exchange).
Getting the default group is a bit tied up, but for this I have some sample code.
private string GetPrimaryGroup(DirectoryEntry aEntry, DirectoryEntry aDomainEntry) { int primaryGroupID = (int)aEntry.Properties["primaryGroupID"].Value; byte[] objectSid = (byte[])aEntry.Properties["objectSid"].Value; StringBuilder escapedGroupSid = new StringBuilder(); // Copy over everything but the last four bytes(sub-authority) // Doing so gives us the RID of the domain for(uint i = 0; i < objectSid.Length - 4; i++) { escapedGroupSid.AppendFormat("\\{0:x2}", objectSid[i]); } //Add the primaryGroupID to the escape string to build the SID of the primaryGroup for(uint i = 0; i < 4; i++) { escapedGroupSid.AppendFormat("\\{0:x2}", (primaryGroupID & 0xFF)); primaryGroupID >>= 8; } //Search the directory for a group with this SID DirectorySearcher searcher = new DirectorySearcher(); if(aDomainEntry != null) { searcher.SearchRoot = aDomainEntry; } searcher.Filter = "(&(objectCategory=Group)(objectSID=" + escapedGroupSid.ToString() + "))"; searcher.PropertiesToLoad.Add("distinguishedName"); return searcher.FindOne().Properties["distinguishedName"][0].ToString(); }
Getting nested groups also takes several steps, and I will have to look for a solution to this if this is a problem.
Mark
PS: as a side note - why are you making a "DirectoryEntry.Invoke (" groups ", null)" call? Why don't you just list the DirectoryEntry.Properties ["memberOf"] property, which is multi-valued (contains multiple values) and has a DN group in it (distinguished name)?
foreach(string groupDN in myUser.Properties["memberOf"]) { string groupName = groupDN; }
OR if you are using .NET 3.5, you can use the new security principal classes in S.DS.AccountManagement. One of them is "UserPrincipal", which has the "GetAuthorizationGroups ()" method, which does all this hard work for you - for free, basically!
See the excellent MSDN article that describes these new features in .NET 3.5 S.DS.