2010-11-26 71 views
12

我正在使用.Net庫的System.DirectoryServices.AccountManagement部分連接到ActiveDirectory。從UserPrincipal對象獲取nETBIOSName

已經叫GetMembers()一個GroupPrincipal對象和過濾結果,我現在有UserPrincipal對象的集合

GroupPrincipal myGroup; // population of this object omitted here 

foreach (UserPrincipal user in myGroup.GetMembers(false).OfType<UserPrincipal>()) 
{ 
    Console.WriteLine(user.SamAccountName); 
} 

上面的代碼示例將打印出用戶名,如「TestUser1」。我需要將它們與來自另一個應用程序的「DOMAIN \ TestUser1」格式的列表進行比較。

如何從UserPrincipal對象獲取「DOMAIN」部分?

我不能只追加一個已知域名,因爲涉及多個域,我需要區分DOMAIN1 \ TestUser1和DOMAIN2 \ TestUser2。

+0

@marc_s的UserPrincipleName包含[email protected]格式名稱 - 我看不到如何輕鬆地將其轉換爲DOMAIN \ user格式(尤其是涉及的域名是已知列表 - 每個生產環境將是與我的開發環境不同的域列表) – Grhm 2010-11-26 11:03:47

+0

您也可以使用'msDS -PrincipalName`屬性如下所述http://stackoverflow.com/questions/10702188/ – 2013-10-29 16:42:48

+2

或者使用`user.Sid.Translate(typeof(System.Security.Principal.NTAccount))。ToString()`獲取Domain \ eac的用戶名h小組成員。請參閱http://stackoverflow.com/questions/6759463 – 2013-10-29 17:32:34

回答

4

你有兩個我能想到的選擇。

  1. 解析,或採取的一切,在[email protected]的權利;
  2. 使用System.DirectoryServices命名空間。

我不知道UserPrincipal,我也不瞭解GroupPrincipal。另一方面,我知道一種實現你想要的工作方式。

[TestCase("LDAP://fully.qualified.domain.name", "TestUser1")] 
public void GetNetBiosName(string ldapUrl, string login) 
    string netBiosName = null; 
    string foundLogin = null; 

    using (DirectoryEntry root = new DirectoryEntry(ldapUrl)) 
     Using (DirectorySearcher searcher = new DirectorySearcher(root) { 
      searcher.SearchScope = SearchScope.Subtree; 
      searcher.PropertiesToLoad.Add("sAMAccountName"); 
      searcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", login); 

      SearchResult result = null; 

      try { 
       result = searcher.FindOne(); 

       if (result == null) 
        if (string.Equals(login, result.GetDirectoryEntry().Properties("sAMAccountName").Value)) 
         foundLogin = result.GetDirectoryEntry().Properties("sAMAccountName").Value 
      } finally { 
       searcher.Dispose(); 
       root.Dispose(); 
       if (result != null) result = null; 
      } 
     } 

    if (!string.IsNullOrEmpty(foundLogin)) 
     using (DirectoryEntry root = new DirectoryEntry(ldapUrl.Insert(7, "CN=Partitions,CN=Configuration,DC=").Replace(".", ",DC=")) 
      Using DirectorySearcher searcher = new DirectorySearcher(root) 
       searcher.Filter = "nETBIOSName=*"; 
       searcher.PropertiesToLoad.Add("cn"); 

       SearchResultCollection results = null; 

       try { 
        results = searcher.FindAll(); 

        if (results != null && results.Count > 0 && results[0] != null) { 
         ResultPropertyValueCollection values = results[0].Properties("cn"); 
         netBiosName = rpvc[0].ToString(); 
       } finally { 
        searcher.Dispose(); 
        root.Dispose(); 

        if (results != null) { 
         results.Dispose(); 
         results = null; 
        } 
       } 
      } 

    Assert.AreEqual("INTRA\TESTUSER1", string.Concat(netBiosName, "\", foundLogin).ToUpperInvariant()) 
} 

本SO問題中可用的其他相關信息或鏈接。
C# Active Directory: Get domain name of user?
How to find the NetBIOS name of a domain

0

您是否嘗試將完全限定的域名傳遞給這個其他應用程序?如果你做fully_qualified_domain\USER,大部分windows API都不會投訴。

2

使用ActiveDs COM庫,它有內置的名稱翻譯的作品,並沒有做任何假設(像其他的答案在這裏)。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using ActiveDs; 

namespace Foo.Repository.AdUserProfile 
{ 
    public class ADUserProfileValueTranslate 
    { 
     public static string ConvertUserPrincipalNameToNetBiosName(string userPrincipleName) 
     { 
      NameTranslate nameTranslate = new NameTranslate(); 
      nameTranslate.Set((int)ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_USER_PRINCIPAL_NAME, userPrincipleName); 
      return nameTranslate.Get((int) ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_NT4); 
     } 
    } 
} 
0

您可以在user.DistinguishedName屬性中查找可能的域。 域1中的用戶應該包含字符串「DC = DOMAIN1」。它絕對不應該包含字符串「DC = DOMAIN2」。

0

正如評論,我認爲這是一個更近的時候一個很好的回答這個問題的人提到:

user.Sid.Translate(typeof(System.Security.Principal.NTAccount)).ToString()