以编程方式检索Active Directory数据的速度比CSVDE或.NET更快

时间:2018-12-05 19:18:44

标签: c# c++ windows active-directory

我是一名开发人员,正在寻找从域控制器检索Active Directory数据的最高效方法。过去,我尝试使用.NET API,并且还使用了CSVDE和LDIFDE命令行工具。

是否有一种更高效,更高性能的编程方式?如有必要,我甚至愿意使用C ++进行系统级编程。

我问的原因是我正在构建一个应用程序,该应用程序可以查找并报告客户端Windows网络上的潜在安全问题。

1 个答案:

答案 0 :(得分:0)

.NET的System.DirectoryServices名称空间(例如DirectoryEntry / DirectorySearcher)是对本机Windows Active Directory服务接口(ADSI)的包装。唯一的性能影响是它是包装器(本机C ++顶部的.NET组件)。

但这不是性能瓶颈所在。每当您从AD中生成报告时,最大的性能影响就是来自网络请求,因此,性能的关键是将网络请求降至最低和/或将报告尽可能靠近域控制器运行,以最大程度地减少回合。行程时间。

System.DirectoryServices.AccountManagement名称空间(例如UserPrincipal)是System.DirectoryServices之上的包装器,根据我的经验,它非常慢,因为您无法控制有多少请求发送给AD (例如,即使您从未使用过它们,它通常也会获取AD对象的 all 属性)。

如果要提高性能,请使用System.DirectoryServices。要提高性能,请记住以下几点:

  1. 使用DirectorySearcher时,总是PropertiesToLoad添加内容。如果您不要求任何内容,它将返回所有具有值的属性。
  2. DirectoryEntry使用属性缓存。如果您访问DirectoryEntry.Properties,它将检查其缓存中是否已具有该属性。如果没有,它将询问AD每个具有值的属性。为避免这种情况,您可以使用DirectoryEntry.RefreshCache()使用特定属性填充缓存,如下所示:
de.RefreshCache(new[] {"company", "sAMAccountName"});
var company = de.Properties["company"]?.Value as string;
var username = de.Properties["sAMAccountName"].Value as string;
  1. 由于1和2,在进行搜索结果时,请勿仅出于读取Properties的目的而使用SearchResult.GetDirectoryEntry()。否则,您最终将回到AD来获取在搜索过程中可能已经获得的属性。请改用PropertiesToLoad
  2. 如果您要生成报告,则很可能会遍历许多帐户,这需要进行大量处理。这意味着.NET的垃圾收集器将没有时间运行,直到循环结束。因此,在继续下一个帐户之前,请确保处置(手动创建或放入DirectoryEntry语句中)using个对象。否则您的程序将消耗大量内存(这是我发生的事情)。
  3. 使用DirectorySearcher.FindAll()时,请确保处置结果(再次调用.Dispose()或将其放入using语句中)。该文档说,如果不这样做,最终将导致内存泄漏。

可能还有很多话不能说,但这完全取决于您在做什么。