C# PrincipalSearcher, returning AD groups for specific OU

17,893

Solution 1

Two things:

  1. there are no groups associated with an OU - an OU is a container which contains users, computers, groups etc. (like a directory that contains files). Is that what you mean? You want to enumerate the group contained inside a given OU??

  2. if so: you're not calling the constructor for the PrincipalContext properly. If you check the MSDN documentation on PrincipalContext constructors, you'll see that the one you're using is the one with a ContextType and a name which stands for the domain name of the context you want to bind to:

    var ctx = new PrincipalContext(ContextType.Domain,"MyOU");
    

    This binds to the MyOU domain - and it binds right at the root of that domain tree.

What you're probably looking for is the constructor with three parameters - a ContextType and two strings - the first one being the domain name as above, and the second one being the start location of your search. So change your PrincipalContext construction to:

var ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN", "OU=MyOU");

and then search again - now you should get only groups that are contained inside the OU=MyOU container.

Solution 2

You could try:

    var myItems = new ArrayList();

    var ctx = new PrincipalContext(ContextType.Domain, Environment.UserDomainName, "OU=Groups,DC=Domain,DC=Com");

    // define a "query-by-example" principal - here, we search for a GroupPrincipal  
    var qbeGroup = new GroupPrincipal(ctx);

    // create your principal searcher passing in the QBE principal     
    var srch = new PrincipalSearcher(qbeGroup);

    // find all matches 
    foreach (Principal found in srch.FindAll())
    {
        var foundGroup = found as GroupPrincipal;

        if (foundGroup != null && foundGroup.IsSecurityGroup == true)
        {
            myItems.Add(foundGroup.Name);
        }
    } 

PrincipalContext requires contextType, Domain and the Container's DN (if you just want to search a container).

foundGroup != null && foundGroup.IsSecurityGroup == true will return all security groups. Which is what you want.

You could also use GroupScope to refine things if you like:

foundGroup != null && foundGroup.GroupScope == GroupScope.Global will narrow the scope to global groups.

Hope that helps.

Share:
17,893
Clu
Author by

Clu

Updated on June 12, 2022

Comments

  • Clu
    Clu almost 2 years

    I'm having a bit of difficultly with this code, specifically with PrincipalSearcher. I'm trying to get a list of all the Groups associated with a specific OU.

    I'm trying to just return "Security" groups under all Group Scopes, excluding distribution groups.

    The issue I'm having is, it's returning these built-in groups in addition to the one's I'm intending to return.

    HelpServicesGroup TelnetClients Administrators Users Guests Print Operators Backup Operators Replicator Remote Desktop Users Network Configuration Operators Performance Monitor Users Performance Log Users Distributed COM Users Domain Computers Domain Controllers Schema Admins Enterprise Admins Cert Publishers Domain Admins Domain Users Domain Guests Group Policy Creator Owners RAS and IAS Servers Server Operators Account Operators Pre-Windows 2000 Compatible Access Incoming Forest Trust Builders Windows Authorization Access Group Terminal Server License Servers DnsAdmins DnsUpdateProxy IIS_WPG

    I'm not sure if perhaps the scope is incorrect or maybe I'm missing some sort of filtering.

    The relevant code segment:

        public static ArrayList GetAllGroups()
        {
            var myItems = new ArrayList();
    
            var ctx = new PrincipalContext(ContextType.Domain,"MyOU");
    
            // define a "query-by-example" principal - here, we search for a GroupPrincipal 
            var qbeGroup = new GroupPrincipal(ctx);
    
            // create your principal searcher passing in the QBE principal    
            var srch = new PrincipalSearcher(qbeGroup);
    
            // find all matches
            foreach (Principal found in srch.FindAll())
            {
                var foundGroup = found as GroupPrincipal;
    
                if (foundGroup != null)
                {
                    myItems.Add(foundGroup.Name);
                }
            }
            return myItems;
        }
    

    How do I get this to exclude the built-in groups?

    Any assistance with this will be greatly appreciated.

    Thank you!

  • Clu
    Clu about 12 years
    Marc, Thank you kindly for that explanation I understand the issue now.
  • Clu
    Clu about 12 years
    Daro, thank you for this alteration to the code, I've implemented a different routine based on the information from Marc S.