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. 


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... 


                        Console.WriteLine("\nWe did not find that group in that domain, perhaps the group resides in a different domain?"); 



Technorati Tags: ,,,

Comments (3)

  1. BooRadely says:

    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.


    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.

  2. hank voight says:

    This is most valuable, thanks!

  3. wiky says:

    PrincipalContext should be disposed.

    using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName))