Link to home
Start Free TrialLog in
Avatar of gsdevEE
gsdevEEFlag for United States of America

asked on

C# - Retrieve Active DIrectory Group's Users whose Membership Is PRIMARY

I need to get the all the users of a "Primary Group".  for example, when a do an LDAP Query on "Domain User" members, i get nothing - this is because all the actuall members who belong to it have "Domain Users" as thier primary group - I already figured out how to get a Users Primary Group (Below)  - Now I need to Get that Primary Groups' Members , for example, I pass in Domain Users and I get back user1, user2, etc - Thanks


public static string GetUsersPrimaryGroup(string samAccountName)
        {
            try
            {
            
                DirectorySearcher srch = Util.SearchUsers(100, samAccountName, false);
                SearchResult userResult = srch.FindOne();
                DirectoryEntry user = new DirectoryEntry(userResult.Path);
                byte[] userSid = user.Properties["objectSid"][0] as byte[];
                user.RefreshCache(new string[] { "primaryGroupId" });
                int primaryGroupID = (int)user.Properties["primaryGroupId"][0];
                byte[] rid = BitConverter.GetBytes(primaryGroupID);
                for (int i = 0; i < rid.Length; i++)
                {
                    userSid.SetValue(rid[i], new long[] { userSid.Length - (rid.Length - i) });
                }
                string adPath = String.Format("LDAP://<SID={0}>", BuildOctetString(userSid));
                DirectoryEntry de = new DirectoryEntry(adPath);
                //We do not want to dispose untill we have the group name, which is why we assign instead of return
                string primaryGroupName = de.Properties["sAMAccountName"][0].ToString();
                return primaryGroupName;
                
            }
            catch (Exception ex)
            {
                //throw to catch in calling method (we want the details/can trace better)
                throw ex;
            }
           
        }
        
        private static string BuildOctetString(byte[] bytes)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                sb.Append(bytes[i].ToString("X2"));
            }
            return sb.ToString();
        }

Open in new window

Avatar of Meir Rivkin
Meir Rivkin
Flag of Israel image

once yo get the primary group name call this method to get all members.

(http://snipplr.com/view.php?codeview&id=4646)
// Get all users from an Active Directory distribution group
public SortedList GetUsersInGroup(string domain, string group)
{
    SortedList groupMemebers = new SortedList();

    string sam = "";
    string fname = "";
    string lname = "";
    string active = "";

    DirectoryEntry de = new DirectoryEntry("LDAP://DC=" + domain + ",DC=com");

    DirectorySearcher ds = new DirectorySearcher(de, "(objectClass=person)");
    ds.Filter = "(memberOf=CN=" + group + ",DC=" + domain + ",DC=com)";

    ds.PropertiesToLoad.Add("givenname");
    ds.PropertiesToLoad.Add("samaccountname");
    ds.PropertiesToLoad.Add("sn");
    ds.PropertiesToLoad.Add("useraccountcontrol");

    foreach (SearchResult sr in ds.FindAll())
    {
        try
        {
            sam = sr.Properties["samaccountname"][0].ToString();
            fname = sr.Properties["givenname"][0].ToString();
            lname = sr.Properties["sn"][0].ToString();
            active = sr.Properties["useraccountcontrol"][0].ToString();
        }
        catch (Exception e)
        {
        }

        // don't grab disabled users
        if (active.ToString() != "514")
        {
            groupMemebers.Add(sam.ToString(), (fname.ToString() + " " + lname.ToString()));
        }
    }

    return groupMemebers;
}

Open in new window

disregard the comment, it search by group name not type
ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gsdevEE

ASKER

sedgwick - thank you for the comment - but the "memberOf" property does not pull objects whose primary group is the object we are searching - thanks for the answer, I actually figured it out 5 minuted later

Here is the result :

 public static string[] GetPrimaryGroupMemberNames(string groupName)
        {
            List members = new List();
            DirectorySearcher srch = Util.SearchGroups(1, groupName, false);
            DirectorySearcher dsearch2 = new DirectorySearcher();
            SearchResultCollection sResult2;
            SearchResult sr = srch.FindOne();
            if(sr != null)
            {
                string name = (string)sr.Properties["name"][0];
                string gSid = Util.ConvertSID((Byte[])sr.Properties["objectSid"][0]);
                  if (gSid == null)
                        return members.ToArray();
                  string rSid = gSid.Substring(gSid.LastIndexOf('-') + 1);
                int irSid;
                int.TryParse(rSid, out irSid);
                dsearch2.PageSize = 500;
                dsearch2.SizeLimit = 500;
                dsearch2.ReferralChasing = ReferralChasingOption.All;
                dsearch2.SearchScope = SearchScope.Subtree;
                dsearch2.Filter = "(&(primaryGroupID=" + rSid + "))";
                dsearch2.SearchRoot = Util.GetRoot(string.Empty);
                sResult2 = dsearch2.FindAll();
                foreach(SearchResult sr2 in sResult2)
                {
                    members.Add(sr2.Properties["cn"][0].ToString());
                }
            }
            Util.DisposeComponents(srch);
            Util.DisposeComponents(dsearch2);
            return members.ToArray();
        }