如何在具有多个树的AD林中的全局编录中搜索用户

我有以下带有两棵树的AD森林:

  1. 域1。 有两个子域Domain2和Domain3
  2. Domain4。 没有子域名。

Domain1的DNS名称是domain1.local 。 Domain4的DNS名称是domain4.local

在每个域中都有一个启用了全局编录的域控制器。

我正在尝试通过其SID从域4获取UserPrincipal。 该程序从Domain2中的计算机运行。

我使用以下代码:

// Running on some machine from Domain2 PrincipalContext context = new PrincipalContext( ContextType.Domain, "dc2.domain2.domain1.local:3268", // Using Global Catalog port and local domain controller "DC=domain1, DC=local", // I guess the problem is here "domain1\\super-admin", // User has all necessary rights across all domains "password"); UserPrincipal principal = UserPrincipal.FindByIdentity(context, "SID-OF-A-USER-FROM-DOMAIN-4"); 

在我的情况下,principal为null(找不到用户)。

在一个树(domain1及其子代)中搜索可以正常使用上面的代码片段,但我不知道如何修改PrincipalContext构造函数的容器参数以真正启用林范围的搜索。

最初我认为“DC = domain1,DC = local”指向了林根,但似乎我在这里有误解。

我知道如果我将容器路径更改为“DC = domain4,DC = local”,那么搜索将起作用,但仅适用于domain4中的用户。

但我真的需要这样一个指向整个林的容器路径,因此我可以使用相同的PrincipalContext从林中的任何域搜索用户。

任何帮助都表示赞赏,特别是如果有人能澄清我的要求是否可以实现。

除了切换到DirectorySearcher之外,我们找不到任何其他解决方案。 因此看起来PrincipalContext类并不完全支持在整个林中进行搜索。

我不能说这个解决方案很理想。 我想它可以调整以获得更好的性能。 但我们真的很失望,无法使用PrincipalContext完成。

以下是我们的代码现在如何工作的粗略概念:

 ... // Here is a list of SIDs of users we want to find (initialized somewhere above) List userSids; // List of sample results. List loadedUsers = new List(); using (DirectorySearcher searcher = new DirectorySearcher(new DirectoryEntry("GC://dc2.domain2.domain1.local"))) { StringBuilder filterStringBuilder = new StringBuilder(); // Just create a single LDAP query for all user SIDs filterStringBuilder.Append("(&(objectClass=user)(|"); foreach (string userSid in users) { filterStringBuilder.AppendFormat("({0}={1})", "objectSid", userSid); } filterStringBuilder.Append("))"); searcher.PageSize = 1000; // Very important to have it here. Otherwise you'll get only 1000 at all. Please refere to DirectorySearcher documentation searcher.Filter = filterStringBuilder.ToString(); // We do not want to go beyond GC searcher.ReferralChasing = ReferralChasingOption.None; searcher.PropertiesToLoad.AddRange( new[] { "DistinguishedName" }); SearchResultCollection results = searcher.FindAll(); foreach (SearchResult searchResult in results) { string distinguishedName = searchResult.Properties["DistinguishedName"][0].ToString(); loadedUsers.Add(distinguishedName); } } ...