C#: Getting members of a group the easy way with .Net 3.5 (Discussion groups, nested, recursive, security groups, etc.)
Just saw this being discussed internally and thought that it was quite useful to a lot of you out there so I thought I'd share. The true boolean to grp.GetMembers tells it to recursively get the nested group members too. I tested this out on discussion groups, security groups, with users and computers and works as expected.
https://msdn2.microsoft.com/en-us/library/bb339975.aspx
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices.AccountManagement;
namespace groupEnum
{
class Program
{
public static string groupName = string.Empty;
public static string domainName = string.Empty;
static void Main(string[] args)
{
groupName = args[0];
domainName = args[1];
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName);
if (grp != null)
{
foreach (Principal p in grp.GetMembers(true))
{
Console.WriteLine(p.Name); //You can add more attributes, samaccountname, UPN, DN, object type, etc...
}
grp.Dispose();
ctx.Dispose();
}
else
{
Console.WriteLine("\nWe did not find that group in that domain, perhaps the group resides in a different domain?");
}
}
}
}
Technorati Tags: C#,DS,Active Directory,.Net 3.5
Comments
Anonymous
January 01, 2003
Update: If you use this code and it blows up with a certain group with the exception: There is no such object on the server. Then: In my case the user it kept blowing up on was a deleted account which still was persistent in the directory because it had not been garbage collected yet. When I ran the exe with elevated permission it completed as expected, but as a regular account you cannot see the object and therefore the framework doesn’t handle this.Anonymous
September 06, 2008
This is most valuable, thanks!Anonymous
July 13, 2009
PrincipalContext should be disposed. using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName)) { ... }