First, I cannot get into why I need this data and I cannot get into specifics about the network. You'll have to trust me there is no other way to get this data other than a PowerShell script to run LDAP queries.
I am working with a network that has multiple forests and multiple domains. There is a trust between all the forests. I am logged into one domain on one of the forests but because of the trust I can query all of them.
I have a CSV file with millions of AD groups. I need to find all the direct members of everyone of the millions of AD groups. A lot of memberships are cross-domain which means I cannot just use the member
property of the AD group and have to, instead, query every domain and check for memberOf
.
I have a PowerShell script that gets this data. For various reasons I cannot share my code but here is what it does:
- creates an array of
System.DirectoryServices.DirectorySearcher
objects for all of my domains - iterate through the CSV file that has a list of every AD group and its
DN
- for each
DN
, loop over theDirectorySearcher
array and find all objects that are amemberOf
the AD group in thatDirectorySearcher
((memberOf=$adGroupDN)
)
The code works. But since I'm dealing with an input list with millions of AD groups the script is awfully slow. Based on my test run calculations it will take more than 2 weeks to get all of the data I need.
I'm wondering if there is a better/faster way to do this?
I thought maybe I could use threading or something but I am not sure if that will help nor am I sure where to start.
Any advise is greatly appreciated.
Adding some additional details...
- My input list are millions of unique group DNs
- I have multiple different forests/domains
- My input group DNs are spread across all the forests/domains
- The groups that are in my input list of group DNs span different forests/domains (
domain1\group1
from my input list hasdomain2\group2
as a member) - I need to get a complete list of every group that is in the groups from my input list
- Because of cross-domain memberships I cannot rely on the
member
attribute of the my input groups. The only way I know to get it is query every DC/domain for all groups that are arememberOf
the groups from my input list. - I can only use PowerShell
- I do not have the ActiveDirectory module and can only use the .NET
DirectorySearcher
At a high level my code looks like this:
$arrayOfDirectorySearcherObjectsForEachDCInMyNetwork = ... code to create an array of System.DirectoryServices.DirectorySearcher objects, one for each DC/domain in my network Foreach ($groupDN in $inputListOfUniqueGroupDNs) { Foreach ($domain in $arrayOfDirectorySearcherObjectsForEachDCInMyNetwork) { ...
- The only way I can think of making it faster is to multi-thread the second for loop where it queries multiple DCs/domains at the same time using runspaces but I cannot figure out how to do this...