如何使用 C# 更好地查询 Active Directory 中的多个域?

2023-12-29

我正在尝试将 LDAP/AD 搜索从仅搜索当前登录的域扩展到搜索 AD 中的所有域。该方法接受带有查询的字符串并返回 LDAPInformation 对象。

当我问的时候,还有比这种方式更好的搜索名字的方法吗?由于按姓氏查找人员时需要使用通配符(例如:Doe*),因此对用户不友好。

    public static LDAPInformation[] GetGlobalAddressListVIAName(string nameQuery)
    {
        var currentForest = Forest.GetCurrentForest();
        var globalCatalog = currentForest.FindGlobalCatalog();

        using (var searcher = globalCatalog.GetDirectorySearcher())
        {
            using (var entry = new DirectoryEntry(searcher.SearchRoot.Path))
            {
                searcher.Filter = "(&(mailnickname=*)(objectClass=user)(displayName=" + nameQuery + "))";
                searcher.PropertyNamesOnly = true;
                searcher.SearchScope = SearchScope.Subtree;
                searcher.Sort.Direction = SortDirection.Ascending;
                searcher.Sort.PropertyName = "displayName";
                return searcher.FindAll().Cast<SearchResult>().Select(result => new LDAPInformation(result.GetDirectoryEntry())).ToArray();
            }
        }
    }

这是对象:

    class LDAPInformation
{
    internal LDAPInformation(DirectoryEntry entry)
    {
        //Section: HASH
        this.sAMAccountName = (string)entry.Properties["sAMAccountName"].Value;

        //Section: Email
        this.Mail = (string)entry.Properties["mail"].Value;

        //Section: Organziation
        this.Description = (string)entry.Properties["description"].Value;
        this.Company = (string)entry.Properties["company"].Value;
        this.Title = (string)entry.Properties["title"].Value;
        this.Department = (string)entry.Properties["department"].Value;

        //Section: Name
        this.DisplayName = (string)entry.Properties["displayName"].Value;
        this.FirstName = (string)entry.Properties["firstName"].Value;
        this.MiddleName = (string)entry.Properties["middleName"].Value;
        this.LastName = (string)entry.Properties["lastName"].Value;

        //Section: Address
        this.StreetAddress = (string)entry.Properties["streetAddress"].Value;
        this.City = (string)entry.Properties["city"].Value;
        this.State = (string)entry.Properties["state"].Value;
        this.PostalCode = (string)entry.Properties["postalCode"].Value;
        this.TelephoneNumber = (string)entry.Properties["telephoneNumber"].Value;
    }

    public string DisplayName
    {
        get;
        private set;
    }

    public string Mail
    {
        get;
        private set;
    }

    public string sAMAccountName
    {
        get;
        private set;
    }

    public string Description
    {
        get;
        private set;
    }

    public string Company
    {
        get;
        private set;
    }

    public string Title
    {
        get;
        private set;
    }

    public string Department
    {
        get;
        private set;
    }

    public string FirstName
    {
        get;
        private set;
    }

    public string MiddleName
    {
        get;
        private set;
    }

    public string LastName
    {
        get;
        private set;
    }

    public string StreetAddress
    {
        get;
        private set;
    }

    public string City
    {
        get;
        private set;
    }

    public string State
    {
        get;
        private set;
    }

    public string PostalCode
    {
        get;
        private set;
    }

    public string TelephoneNumber
    {
        get;
        private set;
    }
}

@Brian Desmond 和@lordzero。可能有点晚了,但我最近自己也在研究这类东西,所以我想分享一下。

为了回答您的问题“您的搜索根是什么?”,lordzero,您可以在不知道 AD 服务器的情况下从它们中找到它。域注册的 PC 将知道 AD 基础设施/森林等。

首先,为“GC://rootDSE”创建一个 DirectoryEntry 您可以从中提取命名上下文、rootDomainNamingContext 或其他。您可以转储第一个根 DSE DirectoryEntry 的所有属性以查看可用的内容。

这是我对我们使用的目录服务服务提供商的实现。

这是取自 DirectorySearcher 包装类

我有一个成员变量。并在构造函数中实例化它。

DirectorySearcher directorySearcher;

在我的初始化方法中,我这样做

        using (DirectoryEntry directoryEntry = new DirectoryEntry(DirectoryConstants.RootDSE))
        {
            // Create a Global Catalog Directory Service Searcher
            string strRootName = directoryEntry.Properties[DirectoryConstants.RootDomainNamingContext].Value.ToString();
            using (DirectoryEntry usersBinding = new DirectoryEntry(DirectoryConstants.GlobalCatalogProtocol + strRootName))
            {
                directorySearcher.SearchRoot = usersBinding;
                directorySearcher.ClientTimeout = timeout;
                directorySearcher.CacheResults = true;
                result = true;
                initialized = true;
            }
        }

DirectoryConstants 类属性

public static string RootDSE { get { return @"GC://rootDSE"; } }
public static string RootDomainNamingContext { get { return "rootDomainNamingContext"; } }
public static string GlobalCatalogProtocol { get { return @"GC://"; } }

我确信这仅适用于登录到域注册 PC 的域用户。身份验证在幕后自动处理。如果您的用户登录到本地帐户或计算机不在域中,您很可能会收到 DirectoryServicesCOMException。

希望这可以帮助。如果您不担心处置和 StyleCop/Sonar 编码违规,请放弃“使用”结构!

上述代码所在的 DirectorySearcherWrapper 类随后由服务提供者代码使用。它像这样分开,因此很容易被模拟,因为不能保证构建机器在执行我们的单元测试时注册到域。

...大部分来自 MSDN/.Net 文档。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 C# 更好地查询 Active Directory 中的多个域? 的相关文章

随机推荐

  • iOS - 理解 UIPanGesture 上的velocityInView

    我正在使用 UIPanGesture 返回velocityInView 根据我的收集 它应该每秒返回点数 我得到的是数亿的数字和很多零 我不会在模拟器中快速移动鼠标 我认为 预先感谢您提供的任何帮助 建议 编辑 请求的代码 显示 呼叫 vo
  • PHP 数字格式

    我有这个字符串 000000000000100 并需要将其转换为 1 00 所以 规则是 将数字除以 100 并使用逗号作为小数分隔符 去掉前导零 保留两位小数 来自PHP 手册页面number format http php net ma
  • 为什么 std::cout << main << std::endl 打印 1? [复制]

    这个问题在这里已经有答案了 include
  • 添加服务引用和添加 Web 引用?

    我正在尝试添加对网络服务的网络引用 http jira atlassian com rpc soap jirasoapservice v2 wsdl http jira atlassian com rpc soap jirasoapserv
  • Kubectl获取节点返回“服务器没有资源类型“节点””

    我安装了 Kubernetes 并执行了 kubeadm init 并从工作线程加入 但是当我运行 kubectl getnodes 时它给出以下响应 服务器没有资源类型 节点 这里可能有什么问题 在 var log messages 中看
  • Linq to XML 简单从节点语句获取属性

    这是代码片段 XDocument themes XDocument Load HttpContext Current Server MapPath Models Themes xml string result var childType
  • 在给定文本中查找 PHP 中特定文本的模式[重复]

    这个问题在这里已经有答案了 我很难找到特定的对象preg match all图案 我有一条文字 很多数据 但我只想找到一个特定的 就像我有一串文本 sadasdasd website https bitcoin org tatic clou
  • C++:如何在 Windows 的“开始”菜单中创建快捷方式

    我想知道如何获取 Windows 上开始菜单文件夹的路径 然后创建可能包含非 ASCII 字符的路径的快捷方式 这是解决方案 它使用 Qt 但也可以不使用 然后只需使用std wstring代替QString 为了连接路径和文件名 您将不得
  • 确定 SQLite 中查询的执行时间

    我正在创建一个用于分析和生成查询的程序 我很好奇 SQLite 中当前是否存在一种方法 以便我可以查询处理查询所需的时间 我无法以任何方式修改我的安装 因此此方法需要开箱即用 我正在用 python 编写我的工具 尽管我想我可以使用计时器类
  • 如何在Delphis MessageDlg中忽略计时器事件

    我在 Delphi 中设置了一个全局异常处理程序 在某些严重的异常情况下 会显示一条错误消息 后跟 Halt 显示错误消息时 Delphi 正在处理消息队列 处理计时器事件 这会导致进一步的错误 我想要的是显示一个不处理计时器事件的错误对话
  • 在进行一些 python 分析后,Django(?)在处理大型数据集时速度非常慢

    我正在将我的旧 PHP 脚本与更新 更精美的 Django 版本和 PHP 脚本进行比较 完全脱离 HTML 并且所有功能都运行得更快 速度快得多 以至于 Django 肯定出了问题 首先 一些背景信息 我有一个页面可以输出销售数据报告 数
  • html5 如何将一个 SVG 变形或动画为另一个?

    我做了一些搜索 但我不得不承认 我对 SVG 没有任何经验 我见过很多现代库 例如 Raphael PaperJS KineticJS EaselJS 但我不知道什么适合这里的目标 也许甚至 CSS 关键帧也能做到这一点 对于这个问题的指出
  • 使用 Javascript 更改元素的 onfocus 处理程序?

    我有一个表单 其中的默认值描述了应该输入该字段的内容 替换标签 当用户聚焦某个字段时 将调用此函数 function clear input element element value element onfocus null onfocu
  • 在哪里可以找到要使用 LDAP 过滤器搜索的完整属性列表?

    作为我的问题的延伸here https stackoverflow com questions 24649579 searching directoryservices to return a list of modified users
  • Jersey 2 中的自定义 MOXyJsonProvider 不起作用?

    我正在阅读答案Moxy 忽略 json 中的无效字段 https stackoverflow com questions 27658173 moxy ignore invalid fields in json该方法与我想做的事情相匹配 所以
  • Wix Bundle源码路径和项目结构

    我正在尝试创建一个引导程序安装程序 它将安装我的应用程序以及运行我的应用程序所需的第三方应用程序 第三方应用程序是一个 exe 包 其中包含许多补充文件 我的问题是 如何将第三方应用程序包含到我的捆绑包中 我是否也必须添加所有补充文件 10
  • 使用nodejs和redis进行发布订阅(node_redis)

    我正在尝试使用 nodejs 和 node redis 构建一个通用的发布 订阅服务器 该服务器接收来自浏览器的带有通道名称的请求 并响应该通道已发布的任何数据 为此 我使用来自浏览器的长轮询请求 并通过在通道上收到消息时发送响应来处理这些
  • Java:int数组用非零元素初始化

    据 JLS 称 int初始化后数组应立即用零填充 然而 我面临的情况并非如此 这种行为首先出现在 JDK 7u4 中 并且也出现在所有后续更新中 我使用 64 位实现 下面的代码抛出异常 public static void main St
  • 在 C 中,const 变量是否保证在内存中不同?

    说到字符串文字 C99 标准规定 6 4 5 6 如果这些数组的元素具有适当的值 则未指定这些数组是否不同 如果程序尝试修改这样的数组 则行为是未定义的 我找不到类似的警告或对 const 变量的明确保证 可以表达一下 x y在上下文中co
  • 如何使用 C# 更好地查询 Active Directory 中的多个域?

    我正在尝试将 LDAP AD 搜索从仅搜索当前登录的域扩展到搜索 AD 中的所有域 该方法接受带有查询的字符串并返回 LDAPInformation 对象 当我问的时候 还有比这种方式更好的搜索名字的方法吗 由于按姓氏查找人员时需要使用通配