How do I enumerate all users and groups from a trusted domain from a child

Posted on 2009-12-25
Last Modified: 2012-05-08
Hello all,

I don't like the where my code is going, so I figured I would ask some guidance.

I need to enumerate all the users and groups when I'm pointed to a child domain.  

Our product needs to load users and groups for very high-speed group membership checking so we can't query the AD in real time.  Normally, this isn't a problem since we can enumerate users and groups just fine when pointing at the PDC.

But...when pointing at a child domain our code is loading the users and groups from the child but not the trusted parent.

Right now, it seems to me that I have to:
1. enumerate all the users and global groups of the child domain
2. figure out what domains the child trusts and then enumerate all the users and global groups for each one.

There has to be a easier way.  Any ideas?


Question by:iunknown21
    LVL 38

    Expert Comment

    I am not much of a code writer. But when querying a domain controller for AD objects, you can use DSqeury in a number of ways to get what you want. Do you think your script writers can use this to their advantage?
    LVL 38

    Expert Comment

    Also Microsoft Developers Network has a list of codes to do pretty much ANYTHING you can think of>

    For instance, enumerating AD Groups and Users:
    LVL 1

    Author Comment

    Thank you ChiefIT,

    I have code (C++ and C#) that enumerates users and groups of a domain; the problem I have is that when I'm pointed at a child domain picking up the parent domain's group membership.  

    What I'm wondering is a way to get the trusted group membership from the child instead of having to query each trusted domain directly.
    LVL 38

    Expert Comment

    Wow, that I wouldn't know.

    C++ was besided me.

    A VBS script using the ADSI or WMI should be able to do it.
    LVL 70

    Expert Comment

    by:Chris Dent

    Hi Gene,

    You mention both a child domain and a trust. Do you mean all domains are within a single Forest?

    Removing the code-level part, you may choose to query the Global Catalog (LDAP connection to a GC server on TCP Port 3268).

    There are limitations, how much of an impact those will have depend on how you use groups.

    The limitations are:

    1. Domain Local Groups are not published into the Global Catalog
    2. Global Groups can only be fully enumerated using a DC which is a member of the groups domain

    Universal Groups on the other hand, which are the most useful in any forest-wide scenario can be fully enumerated using a Global Catalog server in any domain within a Forest.

    tokenGroups perhaps bears investigation as well, but I'm unsure at this point if that holds cross-forest information. Either way, it is restricted to information about Security Groups and won't fly if you're using Distribution Groups.

    I can help with code in C# if you need, but anything more than very basic C++ is beyond me at the moment.


    LVL 1

    Author Comment

    Chris, that is very helpful and I would love to see your c# code.   I can port it if I need to, but I'm pretty sure that I can use C# directly.

    The problem I have is that someone has a forest set up like this:


    My product does real-time file auditing and security and supports group membership filters.  Since file activity happens so incredibly fast I can't check group membership as needed.  

    So what I do is load all the users and groups on a schedule and check against it.  The problem is that if a user points the product at, I don't see the groups from

    What would be best is if I pick up the global groups from Prod.Acme.Com AND

    It was my hope that Proc.Acme.Com would ALSO have all the security groups from
    LVL 70

    Accepted Solution


    A user in Prod.Acme.Com wouldn't be able to be a member of a Global Group in Or do you need to deal with authentication from as well?

    I'm not sure if this will fit in, but it's perhaps worth mentioning:

    If you used something like the .NET class WindowsIdentity to access the users information you'd have access to the Groups property which contains SIDs for each security group:

    Compare the list of SIDs there with your ACL (assuming you store the groups SID when you use it in the filter) and the check is complete. It happens at a much lower level, but this is effectively how NTFS permissions are checked when a user attempts to access something.

    I'm not entirely sure that'll be helpful though which leads onto the next problem.

    If you must support Global Groups across an entire Forest then you must be prepared to query each domain within that Forest independently. The Global Catalog can be used provided you are able to live with the limitations above.

    Either way, you will only fully enumerate Universal Groups if you use the Global Catalogs. No single domain will provide a complete answer about those.

    That means the query list is currently:

    1. Support for Global Groups: Query one DC from each Domain in the Forest
    2. Support for Universal Groups: Query one GC from anywhere in the Forest

    The code for such a query is very simple and goes something like the snippet below. If you're dealing with exceptionally large domains (in excess of 20000 users) then you may improve performance by shifting to System.DirectoryServices.Protocols; more complex to implement, but avoids ADSI entirely.

    // Assumes an authenticated connection
    // Connects to a Global Catalog on the Root Domain Naming Context
    DirectoryEntry adSearchRoot = new DirectoryEntry("GC://SomeDomainController/DC=acme,DC=com");
    // Note that the root domain naming context can be found dynamically. As can Global Catalog
    // servers provided you have a root domain name.
    // Create a filter to find groups from the search base
    // groupType can be used to filter to specific group types if required.
    String adFilter = "(&(objectCategory=group))";
    // Search Constructor
    DirectorySearcher adSearch = new DirectorySearcher(adSearchRoot, adFilter);
    // Enable Paging
    adSearch.PageSize = 1000;
    // Execute the Search
    SearchResultCollection adSearchResults = adSearch.FindAll();
    // Loop through each search result
    foreach (SearchResult adSearchResult in adSearchResults)

    Open in new window

    LVL 1

    Author Closing Comment

    Chris-Dent gave an awesome answer!

    Thank you Chris.

    Featured Post

    Training Course: Java/J2EE and SOA

    This course will cover both core and advanced Java concepts like Database connectivity, Threads, Exception Handling, Collections, JSP, Servlets, XMLHandling, and more. You'll also learn various Java frameworks like Hibernate and Spring.

    Join & Write a Comment

    Do you have users whose passwords are expiring and they are constantly calling you?  Well I sure did and needed a way to put an end to this.  We have a lot of remote users which would not be notified that their passwords were expiring since they wer…
    Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
    This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles from a Windows Server 2008 domain controller to a Windows Server 2012 domain controlle…
    This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles to another domain controller. Log onto the new domain controller with a user account t…

    729 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

    Need Help in Real-Time?

    Connect with top rated Experts

    22 Experts available now in Live!

    Get 1:1 Help Now