You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用LDAP和C#获取域控制器信息、状态及复制状态?

使用LDAP和C#远程获取域控制器信息、运行状态及复制状态

我希望通过LDAP和C#远程获取域控制器的相关信息、运行状态及复制状态(比如在PC1上运行代码,获取PC2的数据)。我知道用WMI可以执行以下查询实现该需求:

SELECT * FROM MSAD_DomainController
then
SELECT * FROM MSAD_ReplCursor where SourceDsaDN like '%{domainControllerName}%'
then
SELECT * FROM MSAD_ReplNeighbor where NamingContextDN like '{NamingContextDN->From above query}'

请问用LDAP时,该如何实现类似WMI查询的功能?我目前用以下C#代码查询域控制器详情:

using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;

class Program
{
    static void Main()
    {
        string domainname = {Domain}; 
        string username = {User};
        string password = {Pass};

        try
        {
            // Using DirectoryEntry for LDAP operations
            string ipAddress = {IP};
            string ldapPath = $"LDAP://{ipAddress}:389/DC={domainname},DC=com";
            using (DirectoryEntry entry = new DirectoryEntry(ldapPath, username, password, AuthenticationTypes.Secure))
            {
                using (DirectorySearcher searcher = new DirectorySearcher(entry))
                {
                    searcher.Filter = "(objectClass=*)"; 
                    searcher.SearchScope = SearchScope.Subtree; 

                    SearchResultCollection results = searcher.FindAll();

                    if (results.Count == 0)
                    {
                        Console.WriteLine("No objects found.");
                    }
                    else
                    {
                        foreach (SearchResult result in results)
                        {
                            Console.WriteLine("Object Information:");
                            
                            if (result.Properties["objectClass"].Count > 0)
                            {
                                Console.Write($"Object Class: ");

                                foreach (var value in result.Properties["objectClass"])
                                {
                                    Console.Write($"{value}, "); // Print each value
                                }
                            }

                            foreach (string propertyName in result.Properties.PropertyNames)
                            {
                                var propertyValues = result.Properties[propertyName];

                                if (propertyValues.Count > 0)
                                {
                                    Console.Write($"{propertyName}: ");

                                    foreach (var value in propertyValues)
                                    {
                                        Console.Write($"{value}, "); // Print each value
                                    }

                                    Console.WriteLine(); // New line after values
                                }
                                else
                                {
                                    Console.WriteLine($"{propertyName}: Not Available or Empty");
                                }
                            }
                            Console.WriteLine("---------------------------------------------------");
                        }
                    }
                }
            }
        }
        catch (ActiveDirectoryObjectNotFoundException ex)
        {
            Console.WriteLine($"Error: {ex.Message} - Check domain name and connectivity.");
        }
        catch (ActiveDirectoryOperationException ex)
        {
            Console.WriteLine($"AD Operation Error: {ex.Message}");
        }
        catch (DirectoryServicesCOMException ex)
        {
            Console.WriteLine($"Directory Services Error: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Unexpected Error: {ex.Message}");
        }
    }
}

解决方案

LDAP可通过查询AD中特定对象类和属性,实现与WMI对应的功能,以下是具体实现方式及优化后的C#代码:

1. 对应MSAD_DomainController:获取域控制器基础信息

域控制器在AD中以nTDSDSA对象类存在,存储路径为CN=Servers,CN={站点名},CN=Sites,CN=Configuration,{域根DN},可直接通过(objectClass=nTDSDSA)过滤查询。

核心属性:

  • dNSHostName:域控制器FQDN
  • serverReference:关联的服务器对象DN
  • whenCreated:域控制器创建时间
  • options:域控制器配置选项

2. 对应MSAD_ReplCursor:获取复制游标信息

复制游标数据存储在域控制器nTDSDSA对象的replPropertyMetaData属性中,也可通过msDS-ReplAttributeMetaData(属性级复制元数据)、msDS-ReplValueMetaData(值级复制元数据)获取更详细的复制状态。

3. 对应MSAD_ReplNeighbor:获取复制邻居信息

复制邻居信息对应AD中的replNeighbor对象,可通过域控制器nTDSDSA对象的replNeighbors属性查询,也可直接访问CN=NTDS Settings,CN={DC名},CN=Servers,CN={站点名},CN=Sites,CN=Configuration,{域根DN}对象的msDS-ReplNeighbors属性。

完整C#代码示例

以下代码实现远程查询指定域控制器的三类目标数据:

using System;
using System.DirectoryServices;

class DomainControllerLdapTool
{
    static void Main()
    {
        string domainRoot = "DC=contoso,DC=com";
        string targetDcIp = "192.168.1.10";
        string authUser = "contoso\\domain_reader";
        string authPass = "YourSecurePassword";

        try
        {
            // 1. 查询域控制器基础信息
            Console.WriteLine("=== 域控制器基础信息 ===");
            string configPartition = $"CN=Configuration,{domainRoot}";
            using (var configEntry = new DirectoryEntry($"LDAP://{targetDcIp}:389/{configPartition}", authUser, authPass, AuthenticationTypes.Secure))
            {
                var dcSearcher = new DirectorySearcher(configEntry)
                {
                    Filter = "(objectClass=nTDSDSA)",
                    SearchScope = SearchScope.Subtree,
                    PropertiesToLoad = { "dNSHostName", "serverReference", "whenCreated", "options" }
                };

                var dcResult = dcSearcher.FindOne();
                if (dcResult != null)
                {
                    Console.WriteLine($"FQDN: {dcResult.Properties["dNSHostName"][0]}");
                    Console.WriteLine($"服务器DN: {dcResult.Properties["serverReference"][0]}");
                    Console.WriteLine($"创建时间: {dcResult.Properties["whenCreated"][0]}");
                    Console.WriteLine($"配置选项: {dcResult.Properties["options"][0]}");
                }
            }

            // 2. 查询复制游标信息(以域分区元数据为例)
            Console.WriteLine("\n=== 复制游标信息 ===");
            using (var domainEntry = new DirectoryEntry($"LDAP://{targetDcIp}:389/{domainRoot}", authUser, authPass, AuthenticationTypes.Secure))
            {
                var metaSearcher = new DirectorySearcher(domainEntry)
                {
                    Filter = "(objectClass=domain)",
                    PropertiesToLoad = { "msDS-ReplAttributeMetaData" }
                };

                var metaResult = metaSearcher.FindOne();
                if (metaResult != null && metaResult.Properties["msDS-ReplAttributeMetaData"].Count > 0)
                {
                    foreach (byte[] metaData in metaResult.Properties["msDS-ReplAttributeMetaData"])
                    {
                        // 二进制元数据需按AD规范解析,此处简化输出
                        Console.WriteLine($"元数据片段: {BitConverter.ToString(metaData).Substring(0, 60)}...");
                    }
                }
            }

            // 3. 查询复制邻居信息
            Console.WriteLine("\n=== 复制邻居信息 ===");
            using (var configEntry = new DirectoryEntry($"LDAP://{targetDcIp}:389/{configPartition}", authUser, authPass, AuthenticationTypes.Secure))
            {
                // 先定位目标DC的NTDS Settings对象
                var ntdsSearcher = new DirectorySearcher(configEntry)
                {
                    Filter = "(&(objectClass=nTDSDSA)(dNSHostName=dc01.contoso.com))", // 替换为目标DC的FQDN
                    PropertiesToLoad = { "replNeighbors" }
                };

                var ntdsResult = ntdsSearcher.FindOne();
                if (ntdsResult != null && ntdsResult.Properties["replNeighbors"].Count > 0)
                {
                    foreach (string neighborDn in ntdsResult.Properties["replNeighbors"])
                    {
                        Console.WriteLine($"\n邻居DN: {neighborDn}");
                        using (var neighborEntry = new DirectoryEntry($"LDAP://{targetDcIp}:389/{neighborDn}", authUser, authPass, AuthenticationTypes.Secure))
                        {
                            Console.WriteLine($"状态: {neighborEntry.Properties["replState"]?[0] ?? "未知"}");
                            Console.WriteLine($"上次成功复制: {neighborEntry.Properties["lastSuccessfulSync"]?[0] ?? "无记录"}");
                        }
                    }
                }
            }
        }
        catch (DirectoryServicesCOMException ex)
        {
            Console.WriteLine($"LDAP错误: {ex.Message}, 错误码: {ex.ErrorCode}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"异常: {ex.Message}");
        }
    }
}

注意事项

  • 确保运行代码的设备能访问目标域控制器的LDAP端口(默认389,SSL用636)
  • 所用账号需具备读取AD配置分区和域分区的权限
  • 复制元数据为二进制格式,需参照AD官方文档解析具体字段

内容的提问来源于stack exchange,提问作者NeoGenesis521

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 01:23:13