代码之家  ›  专栏  ›  技术社区  ›  Grhm

从用户主体对象获取nETBIOSName

  •  12
  • Grhm  · 技术社区  · 14 年前

    我正在使用.Net库的System.DirectoryServices.AccountManagement部分与ActiveDirectory接口。

    在对GroupPrincipal对象调用GetMembers()并过滤结果之后,我现在有了一个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对象中获取“域”部分?

    我不能仅仅附加一个已知的域名,因为涉及多个域,我需要区分DOMAIN1\TestUser1和DOMAIN2\TestUser2。

    5 回复  |  直到 14 年前
        1
  •  4
  •   Community Tales Farias    7 年前

    你有两个选择我可以考虑。

    1. 解析或获取所有正在进行的操作 name@fully.qualified.domain.name ;
    2. 使用 System.DirectoryServices 命名空间。

    我不知道 用户主体 ,我也不知道 集团负责人 . 另一方面,我知道一种实现你所想要的工作方式。

    [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

        2
  •  2
  •   Jeff    13 年前

    使用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);
            }
        }
    }
    
        3
  •  0
  •   Scott Chamberlain    14 年前

    您是否尝试将完全限定的域名传递给此其他应用程序?如果你这么做的话,大多数windows API都不会抱怨 fully_qualified_domain\USER .

        4
  •  0
  •   GC.    12 年前

    您可以在user.DistinguishedName属性中查找可能的域。 域1中的用户应包含字符串“DC=DOMAIN1”。它绝对不应该包含字符串“DC=DOMAIN2”。

        5
  •  0
  •   Jeff    7 年前

    正如在对这个问题的评论中提到的,我认为这是一个很好的回答:

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