2013-01-02 9 views
11

पूरी तरह से योग्य सक्रिय निर्देशिका डोमेन नाम से नेटबीओएस डोमेन नाम प्राप्त करना कभी-कभी एक कठिन कार्य होता है। मुझे एक अच्छा जवाब मिला hereएक जटिल पर्यावरण में FQDN का उपयोग कर नेटबीओएसओ डोमेन नाम कैसे प्राप्त करें

कई जंगलों वाले वातावरण में यह दृष्टिकोण तब तक काम नहीं करेगा जब पीसी जंगल में नहीं है जो आप पूछ रहे हैं। ऐसा इसलिए है क्योंकि LDAP://RootDSE कंप्यूटर के डोमेन के लिए जानकारी पूछेगा।

कुछ पूछ सकते हैं: इतना जटिल क्यों?

ActiveDirectory.Domain.GetComputerDomain().Name; 

या बस उपयोगकर्ता के डोमेन नाम प्राप्त: पूरी तरह से

Environment.GetEnvironmentVariable("USERDOMAIN"); 

या

Environment.UserDomainName; 

लेकिन NetBIOS डोमेन नाम हो सकता है कुछ बस पहले डॉट द्वारा प्राप्त करने से पहले नाम का उपयोग अलग, और आप या आपका कंप्यूटर एक अलग डोमेन या जंगल में हो सकता है! तो यह दृष्टिकोण केवल एक साधारण वातावरण में प्रयोग योग्य है।

DJ KRAZE’s समाधान को क्रॉस डोमेन क्वेरीज़ को अनुमति देने के लिए केवल एक छोटा संशोधन की आवश्यकता है। यह एक ट्रस्ट रिश्ते को मानता है!

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; 
    } 
+0

आप क्यू एंड ए प्रारूप, या में यह लिखना चाहिए (संभवतः) अपने बेहतर उत्तर मूल प्रश्न के साथ जाना चाहिए। –

+0

मेरा संपादन अनुरोध अस्वीकार कर दिया गया था क्योंकि "मूल पोस्ट में संपादन बहुत अधिक बदलता है" – Daro

+0

इसे एक अलग उत्तर के रूप में पोस्ट करें। अधिक प्रतिनिधि वाले किसी को बाद में उन्हें विलय करने में सक्षम होना चाहिए। –

उत्तर

8

तुम भी DsGetDcName एपीआई, जो आप के लिए सभी आसपास monkeying करना होगा उपयोग कर सकते हैं। यदि आप जिस डोमेन से पूछताछ कर रहे हैं वह स्थानीय कंप्यूटर है तो यह कॉल को कैश भी करेगा और नेटवर्क को भी हिट नहीं करेगा।

आप

उपयोग की क्षमताओं पर अतिरिक्त शर्तें होती हैं:

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); 
    } 
} 

पी/आह्वान:

[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; 
+2

यह वर्णित के रूप में कार्य करता है, लेकिन मुझे एक बदलाव करना पड़ा: संरचना 'DomainControllerInfo' एक वर्ग होना चाहिए था। विधि 'मार्शल.पीटीटीओस्ट्रक्चर' ने इसे अनिवार्य किया। –

संबंधित मुद्दे