Solved

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

Posted on 2010-08-25
4
1,305 Views
Last Modified: 2013-11-07
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

0
Comment
Question by:gsdevEE
  • 2
4 Comments
 
LVL 42

Expert Comment

by:sedgwick
ID: 33522292
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

0
 
LVL 42

Expert Comment

by:sedgwick
ID: 33522300
disregard the comment, it search by group name not type
0
 
LVL 70

Accepted Solution

by:
Chris Dent earned 500 total points
ID: 33522305

It should be pretty simple, two parts, first is to retrieve the PrimaryGroupToken value from the group, then execute a search:


DirectorySearcher ADSearch = new DirectorySearcher("(primaryGroupID=" + PrimaryGroupToken + ")");
SearchResultCollection Results = ADSearch.FindAll();


Chris
0
 

Author Closing Comment

by:gsdevEE
ID: 33538370
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();
        }
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, we will see the basic design consideration while designing a Multi-tenant web application in a simple manner. Though, many frameworks are available in the market to develop a multi - tenant application, but do they provide data, cod…
This script can help you clean up your user profile database by comparing profiles to Active Directory users in a particular OU, and removing the profiles that don't match.
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

832 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question