First, I have to enumerate all the AD groups of the current user. Getting the SID and the name is easy:
foreach(var group in WindowsIdentity.GetCurrent().Groups)
{
var sid = new SecurityIdentifier(group.Value);
string name = (group.Translate(typeof(NTAccount)) as NTAccount).Value;
}
Then I need to determine the number of members in each of the groups, and I can't get that to work. I guess I need a way to get the distinguished name of the groups of the current users. Any idea how to get that?
What I did so far: I tried a WMI query like this, but it returns no results because I would need the fully qualified domain name but NTAccount
gives me only the "friendly" domain account (DOMAIN\group):
SELECT PartComponent FROM Win32_GroupUser
WHERE (GroupComponent = "Win32_Group.Domain='somedomain', Name='somegroup'")
Then I tried LDAP, working around the missing path/Distinguished Name by binding to the SID of the group:
var adGroupEntry = new DirectoryEntry(String.Format("LDAP://<SID={0}>", group.Value));
if (adGroupEntry != null)
{
IEnumerable members = adGroupEntry.Invoke("Members", null) as IEnumerable;
if (members != null)
{
foreach (object member in members)
{
noOfMembers++;
}
}
}
It finds the group, the name property returns the correct value, however Members
never contains any elements. If I would know the full LDAP path for a group (like when I hard-code it), the code above would actually yield the correct number of users in the group.
What am I missing here? I'm not very familiar with Active Directory or WMI.
Restrictions:
System.DirectoryServices.AccountManagement
.I can repro your problem in my environment. It sounds like a bug in ADSI to me.
The returned COM object doesn't work if you are using serverless binding and SID binding at the same time.
I could workaround that by not using serverless bindnig. i.e. using this LDAP://*yourdomain.com*/<SID={0}>
instead
I could also workaround that by binding the object again.
var adGroupEntry = new DirectoryEntry(String.Format("LDAP://<SID={0}>",group.Value));
string dn = adGroupEntry.Properties["distinguishedName"].Value as string;
DirectoryEntry de = new DirectoryEntry("LDAP://" + dn);
if (de != null)
{
IEnumerable members = de.Invoke("Members", null) as IEnumerable;
if (members != null)
{
foreach (object member in members)
{
noOfMembers++;
}
}
}