2010-11-26 2 views
12

Я использую часть .Net библиотеки System.DirectoryServices.AccountManagement для взаимодействия с ActiveDirectory.Получить nETBIOSName из объекта UserPrincipal

Назвав 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».

Как я могу получить часть DOMAIN из объекта UserPrincipal?

Я не могу просто добавить известное доменное имя, так как есть несколько доменов, и мне нужно различать DOMAIN1 \ TestUser1 и DOMAIN2 \ TestUser2.

+0

@marc_s В UserPrincipleName содержит имя в формате [email protected] - Я не вижу, как легко преобразовать это в формат DOMAIN \ user (особенно, поскольку домены участвуют в известном списке - каждая производственная среда будет другим списком доменов, чем моя окружение dev) – 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()` для получения домена \ Имя пользователя eac ч участник группы. См. 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()) 
} 

Дополнительная информация или ссылки, доступные в этом вопросе СО.
C# Active Directory: Get domain name of user?
How to find the NetBIOS name of a domain

0

Вы пробовали передать полное доменное имя этому другому приложению? Большинство API окон не будут жаловаться, если вы делаете fully_qualified_domain\USER.

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() 
Смежные вопросы