65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在不硬编码域名的情况下查询 Active Directory

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (5投票s)

2013 年 10 月 11 日

CPOL

3分钟阅读

viewsIcon

38522

能够编写代码查询当前域而不必硬编码域名会很有用。 本文将向您展示

能够编写代码查询当前域而不必硬编码域名会很有用。 本文将向您展示如何做到这一点。

场景

假设您有两个 Active Directory 林,一个生产林和一个开发林:它们分别称为 prod.com (PROD) 和 dev.com (DEV)。 您需要在 dev.com 中开发代码,然后才能将其部署到 prod.com。 您认为最好编写一段代码,其中不包含对开发域的硬编码引用,这样在部署时就不需要更改代码。

解决方案

这可以通过使用 RootDSE 来实现。 test.com 的一个示例 distinguishedName 可能是 CN=TestGroup1,OU=Groups,DC=test,DC=com。 后两个“块”(DC=test,DC=com)也称为 namingContext。 如果它们恰好是当前域,那么它们就称为 defaultNamingContext

为了弄清楚这一点,请想象一个 Active Directory 林,其中有两个域:root.com 是顶级域,child.root.com 是 root.com 的子域。 如果您登录到 root.com 中的工作站,您的 defaultNamingContext 将是 root.com。 如果您登录到 child.root.com 中的工作站,您的 defaultNamingContext 将是 child.root.com*。

那么,这对我们有什么帮助呢?

如果我们能从 RootDSE 中检索出 defaultNamingContext,我们就可以使用它代替 distinguishedName 的一部分。 例如,“CN=TestGroup1,OU=Groups,” + defaultNamingContext。

*在这两种情况下,还有一个 rootDomainNamingContext,即 root.com。

如何在 C# 中获取 defaultNamingContext

            string defaultNamingContext;
            using (DirectoryEntry rootDSE = new DirectoryEntry("LDAP://RootDSE"))
            {
                defaultNamingContext = rootDSE.Properties["defaultNamingContext"].Value.ToString();
            }
            Console.WriteLine("正在访问域: {0}", defaultNamingContext);

如何在 VB.Net 中获取 defaultNamingContext

        Dim defaultNamingContext As String
        Using rootDSE As New DirectoryEntry("LDAP://RootDSE")
            defaultNamingContext = rootDSE.Properties("defaultNamingContext").Value.ToString()
        End Using
        Console.WriteLine("正在访问域: {0}", defaultNamingContext)
 

如何在 IronPython 中获取 defaultNamingContext

        rootDSE = DirectoryEntry("LDAP://RootDSE")
        defaultNamingContext = rootDSE.Properties["defaultNamingContext"].Value
        Console.WriteLine("正在访问域: {0}", defaultNamingContext)

 

RootDSE 还有其他有用的属性。 以下是列出属性的 C# 和 VB.net 代码片段。 您可以使用 LDP 工具绑定到目录来查看相同的信息。

如何在 C# 中列出 RootDSE 的属性

            using (DirectoryEntry rootDSE = new DirectoryEntry("LDAP://RootDSE"))
            {
                Console.WriteLine("\r\n具有单个值的属性:");
                foreach (string propertyName in rootDSE.Properties.PropertyNames)
                {
                    if (rootDSE.Properties[propertyName].Count == 1)
                    {
                        Console.WriteLine("{0,30} = {1}", propertyName,
                            rootDSE.Properties[propertyName].Value);
                        continue;
                    }
                }
                Console.WriteLine("\r\n具有多个值的属性:");
                foreach (string propertyName in rootDSE.Properties.PropertyNames)
                {
                    if (rootDSE.Properties[propertyName].Count > 1)
                    {
                        Console.WriteLine("    {0}:", propertyName);
                        foreach (object obj in (object[])(rootDSE.Properties[propertyName].Value))
                        {
                            Console.WriteLine("        {0}", obj.ToString());
                        }
                    }
                }
            }
 

如何在 VB.Net 中列出 RootDSE 的属性

        Using rootDSE As New DirectoryEntry("LDAP://RootDSE")
            Console.WriteLine(vbCrLf + "具有单个值的属性:")
            For Each propertyName As String In rootDSE.Properties.PropertyNames
                If rootDSE.Properties(propertyName).Count = 1 Then
                    Console.WriteLine("{0,30} = {1}", propertyName, _
                            rootDSE.Properties(propertyName).Value.ToString())
                    Continue For
                End If
            Next
            Console.WriteLine(vbCrLf + "具有多个值的属性:")
            For Each propertyName As String In rootDSE.Properties.PropertyNames
                If rootDSE.Properties(propertyName).Count > 1 Then
                    Console.WriteLine("    {0}:", propertyName)
                    For Each obj As Object In CType(rootDSE.Properties(propertyName).Value, Object())
                        Console.WriteLine("        {0}", obj.ToString())
                    Next
                End If
            Next
        End Using
 

注意:我通常是 C# 开发者,所以我的 VB.Net 代码可能写得不好。 实际上,我的 C# 代码也可能写得不好,但就这样吧。 :-)

© . All rights reserved.