Which Groups Does WindowsIdentity.Groups Return?

WindowsIdentity exposes a Groups property which returns a collection of IdentityReferences for the groups that a particular user is a member of.  However, if you look closely, you’ll find that these returned groups won’t necessarily include all of the groups that the user is a member of.

Under the covers, WindowsIdentity populates the groups collection by querying Windows for information on the groups that the user token is a member of.  However, before returning this list, the Groups property filters out some of the returned groups.

Specifically, any groups which were on the token for deny-only will not be returned in the Groups collection.  Similarly, a group which is the SE_GROUP_LOGON_ID will not be returned.

Generally, this is exactly the behavior you want.  For instance, if your application is going allow a specific action because the user is a member of a group, you don’t want to allow it if the user is a member of the group for deny-only.

If you want to retrieve all of the groups however, there’s not an easy built-in way for you to do this.  Instead, you’ll have to P/Invoke to the GetTokenInformation API to retrieve the groups yourself.

It can be interesting to dump out the groups that specific users are part of — here’s a simple little snippet of code that does just that.  (And uses some of those fancy new C# 3.0 features to display them grouped by domain):

    public static void Main()


        using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent())


            var groups = // Get all of the groups from our account, and translate them from IdentityReferences to NTAccounts  

                        from groupIdentity in currentIdentity.Groups

                        where groupIdentity.IsValidTargetType(typeof(NTAccount))

                        select groupIdentity.Translate(typeof(NTAccount)) as NTAccount into ntAccounts


                        // Sort the NTAccounts by their account name

                        let domainName = ntAccounts.GetDomainName()

                        let groupName = ntAccounts.GetAccountName()

                        orderby domainName


                        // Group the sorted accounts by the domain they belong to, and sort the grouped groups by domain name

                        group ntAccounts by domainName into domainGroups

                        orderby domainGroups.Key

                        select domainGroups;


            foreach (var domainGroups in groups)


                Console.WriteLine(“Groups from domain: {0}”, domainGroups.Key);


                foreach (var group in domainGroups)


                    Console.WriteLine(”    {0}”, group.GetAccountName());






    private static string GetDomainName(this NTAccount account)


        string[] split = account.Value.Split(‘\\’);

        return split.Length == 1 ? String.Empty : split[0];



    private static string GetAccountName(this NTAccount account)


        string[] split = account.Value.Split(‘\\’);

        return split[split.Length – 1];


Comments (1)

  1. Britney Spears says:

    This is quite helpful! Thanks for sharing your code.

Skip to main content