[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1431
  • Last Modified:

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

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?


  • 3
  • 3
  • 2
1 Solution
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?

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:

iunknown21Author Commented:
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.
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

Wow, that I wouldn't know.

C++ was besided me.

A VBS script using the ADSI or WMI should be able to do it.
Chris DentPowerShell DeveloperCommented:

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.


iunknown21Author Commented:
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:

- Acme.com
-- Prod.Acme.com

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 Prod.Acme.com, I don't see the groups from Acme.com.

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

It was my hope that Proc.Acme.Com would ALSO have all the security groups from Acme.com.
Chris DentPowerShell DeveloperCommented:

A user in Prod.Acme.Com wouldn't be able to be a member of a Global Group in Acme.com. Or do you need to deal with authentication from Acme.com 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

iunknown21Author Commented:
Chris-Dent gave an awesome answer!

Thank you Chris.

Featured Post

Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

  • 3
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now