3

I have some code to check if a domain user is a member of the machines administrators group:

public static bool ActiveDirectoryGroupMembershipOk(string userid, string groupName)
{
    using (PrincipalContext ctx = new PrincipalContext(ContextType.Machine, "my_pc_name"))
    {
        using (GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "administrators"))
        {
            if (grp != null)
            {
                foreach (Principal p in grp.GetMembers(false))
                {
                    if (p is UserPrincipal && p.SamAccountName.Equals(userid, StringComparison.InvariantCultureIgnoreCase))
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

It works, but the below code line takes some seconds to complete:

using (GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "administrators"))

Is there a faster way to lookup the membership?

I don't know if it is important or not, but the userid is a Domain User and the windows group is on the local PC.

2
  • AD in my experience is always slow so I tend to cache the results. In your case, i would use a class global variable grp and call FindByidentity just once
    – Pikoh
    Commented Apr 4, 2016 at 10:11
  • I do that per user. So it is my first request, that is slow. I just read a different post about looking at the user's memberships rather than the members of a group - and that could be faster. Link But I could not get that code to work.
    – Mr. Blonde
    Commented Apr 4, 2016 at 10:18

2 Answers 2

1

I found that it seems to be faster not to look up the user in a group but instead to check the user's role membership.

Here is the code that performs faster than the code in my question:

public static bool ActiveDirectoryGroupMembershipOk(string userid, string groupName)
{
    bool membershipOk = false;
    using (var pc = new PrincipalContext(ContextType.Machine, "my_pc_name"))
    {
        using (var p = Principal.FindByIdentity(pc, IdentityType.SamAccountName, userid))
        {
            // if user account exists, check the group membership
            if(p != null)
            {
                System.Security.Principal.WindowsIdentity wi = new System.Security.Principal.WindowsIdentity(userid);
                System.Security.Principal.WindowsPrincipal wp = new System.Security.Principal.WindowsPrincipal(wi);
                membershipOk = wp.IsInRole(groupName);
            }
        }
    }
    return membershipOk;
}
0

I found a better way to do this still (assuming an AD domain), using part of Mr. Blonde's answer:

public static bool ActiveDirectoryGroupMembershipOk(String userid, String groupname)
{
    PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, userid);
    GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, groupname);

    return user.IsMemberOf(group);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.