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






4.67/5 (5投票s)
能够编写代码查询当前域而不必硬编码域名会很有用。 本文将向您展示
能够编写代码查询当前域而不必硬编码域名会很有用。 本文将向您展示如何做到这一点。
场景
假设您有两个 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# 代码也可能写得不好,但就这样吧。 :-)