如何在复杂环境中使用FQDN获取NETBIOS域名

从完全限定的Active Directory域名获取NETBIOS域名有时是一项繁琐的工作。 我在这里找到了一个好的答案。

在具有多个林的环境中,如果PC不在您正在查询的林中,则此方法将不起作用。 这是因为LDAP://RootDSE将查询计算机域的信息。

有人可能会问:为什么这么复杂? 只需在检索到的第一个点之前使用该名称:

 ActiveDirectory.Domain.GetComputerDomain().Name; 

或者只是获取用户的域名:

 Environment.GetEnvironmentVariable("USERDOMAIN"); 

要么

 Environment.UserDomainName; 

但是NETBIOS域名可能完全不同,您或您的计算机可能位于不同的域或林中! 所以这种方法只能在简单的环境中使用。

DJ KRAZE的解决方案只需要一个小的修改就可以进行跨域查询。 这假设了一种信任关系!

 private string GetNetbiosDomainName(string dnsDomainName) { string netbiosDomainName = string.Empty; DirectoryEntry rootDSE = new DirectoryEntry(string.Format("LDAP://{0}/RootDSE",dnsDomainName)); string configurationNamingContext = rootDSE.Properties["configurationNamingContext"][0].ToString(); DirectoryEntry searchRoot = new DirectoryEntry("LDAP://cn=Partitions," + configurationNamingContext); DirectorySearcher searcher = new DirectorySearcher(searchRoot); searcher.SearchScope = SearchScope.OneLevel; searcher.PropertiesToLoad.Add("netbiosname"); searcher.Filter = string.Format("(&(objectcategory=Crossref)(dnsRoot={0})(netBIOSName=*))", dnsDomainName); SearchResult result = searcher.FindOne(); if (result != null) { netbiosDomainName = result.Properties["netbiosname"][0].ToString(); } return netbiosDomainName; } 

您还可以使用DsGetDcName API,它将为您完成所有的编辑工作。 如果您要查询的域是本地计算机,它还会缓存呼叫,甚至不会访问网络。

如果您对该function有其他要求

使用:

 internal static string GetNetbiosNameForDomain(string dns) { IntPtr pDomainInfo; int result = DsGetDcName(null, dns, IntPtr.Zero, null, DSGETDCNAME_FLAGS.DS_IS_DNS_NAME | DSGETDCNAME_FLAGS.DS_RETURN_FLAT_NAME, out pDomainInfo); try { if (result != ERROR_SUCCESS) throw new Win32Exception(result); var dcinfo = new DomainControllerInfo(); Marshal.PtrToStructure(pDomainInfo, dcinfo); return dcinfo.DomainName; } finally { if (pDomainInfo != IntPtr.Zero) NetApiBufferFree(pDomainInfo); } } 

的P / Invoke:

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private class DomainControllerInfo { public string DomainControllerName; public string DomainControllerAddress; public int DomainControllerAddressType; public Guid DomainGuid; public string DomainName; public string DnsForestName; public int Flags; public string DcSiteName; public string ClientSiteName; } [Flags] private enum DSGETDCNAME_FLAGS : uint { DS_FORCE_REDISCOVERY = 0x00000001, DS_DIRECTORY_SERVICE_REQUIRED = 0x00000010, DS_DIRECTORY_SERVICE_PREFERRED = 0x00000020, DS_GC_SERVER_REQUIRED = 0x00000040, DS_PDC_REQUIRED = 0x00000080, DS_BACKGROUND_ONLY = 0x00000100, DS_IP_REQUIRED = 0x00000200, DS_KDC_REQUIRED = 0x00000400, DS_TIMESERV_REQUIRED = 0x00000800, DS_WRITABLE_REQUIRED = 0x00001000, DS_GOOD_TIMESERV_PREFERRED = 0x00002000, DS_AVOID_SELF = 0x00004000, DS_ONLY_LDAP_NEEDED = 0x00008000, DS_IS_FLAT_NAME = 0x00010000, DS_IS_DNS_NAME = 0x00020000, DS_RETURN_DNS_NAME = 0x40000000, DS_RETURN_FLAT_NAME = 0x80000000 } [DllImport("Netapi32.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "DsGetDcNameW", CharSet = CharSet.Unicode)] private static extern int DsGetDcName( [In] string computerName, [In] string domainName, [In] IntPtr domainGuid, [In] string siteName, [In] DSGETDCNAME_FLAGS flags, [Out] out IntPtr domainControllerInfo); [DllImport("Netapi32.dll")] private static extern int NetApiBufferFree( [In] IntPtr buffer); private const int ERROR_SUCCESS = 0;