【问题标题】:Where is the domain name in a UserPrincipal object?UserPrincipal 对象中的域名在哪里?
【发布时间】:2012-05-22 12:37:25
【问题描述】:

我正在使用 System.DirectoryServices.ActiveDirectory 类来查找所有 Active Directory 用户。代码很简单:

var context = new PrincipalContext(ContextType.Domain);
var searcher = new PrincipalSearcher(new UserPrincipal(context));
var results = searcher.FindAll();

我想以“友好”(又名“pre-Windows 2000”格式)获取域限定用户名,例如。 “CONTOSO\SmithJ”。 UserPrincipal.SamAccountName 给了我用户名部分,但我如何获得域部分?我不能假设域与机器或当前用户的域相同。

【问题讨论】:

标签: .net active-directory directoryservices


【解决方案1】:

对于 AD DS,msDS-PrincipalName 的值是 NetBIOS 域名,后跟一个反斜杠(“\”)。

您可以使用:

/* Retreiving the root domain attributes
 */ 
sFromWhere = "LDAP://DC_DNS_NAME:389/dc=dom,dc=fr"; 
DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "AdminLogin", "PWD"); 

DirectorySearcher dsLookForDomain = new DirectorySearcher(deBase); 
dsLookForDomain.Filter = "(objectClass=*)"; 
dsLookForDomain.SearchScope = SearchScope.base; 
dsLookForDomain.PropertiesToLoad.Add("msDS-PrincipalName"); 

SearchResult srcDomains = dsLookForDomain.FindOne();

【讨论】:

【解决方案2】:

好的,这是我使用 JPBlanc 的答案和answer linked by MichaelZ 得出的最终代码。它显示每个用户的 SID、显示名称和域\用户名。

    var ldapUrl = "LDAP://" + defaultNamingContext;

    using (var rootDe = new DirectoryEntry(ldapUrl))
    using (var searcher = new DirectorySearcher(rootDe))
    {
        searcher.SearchScope = SearchScope.Subtree;
        searcher.PropertiesToLoad.Add("objectSid");
        searcher.PropertiesToLoad.Add("displayName");
        searcher.PropertiesToLoad.Add("msDS-PrincipalName");
        searcher.Filter = "(&(objectClass=user)(objectCategory=person))";

        var results = searcher.FindAll();

        foreach (SearchResult result in results)
        {
            var qualifiedUsername = GetSinglePropertyValue(result, "msDS-PrincipalName");
            var displayName = GetSinglePropertyValue(result, "displayName");
            var sid = new SecurityIdentifier((byte[])GetSinglePropertyValue(result,"objectSid"), 0);

            Console.WriteLine("User: {0}\r\n\tDisplay name: {1}\r\n\tSID: {2}",
                qualifiedUsername, displayName, sid);
        }
    }

    private static object GetSinglePropertyValue(SearchResult result, string propertyName)
    {
        var value = result.Properties[propertyName];
        if (value.Count == 0)
            return null;
        if (value.Count == 1)
            return value[0];
        throw new ApplicationException(string.Format("Property '{0}' has {1} values for {2}",
            propertyName, value.Count, result.Path));
    }

并获得机器域的默认命名上下文(如answered here):

private static string GetDefaultNamingContext()
{
    // This check is fast
    try
    {
        Domain.GetComputerDomain();
    }
    catch (ActiveDirectoryObjectNotFoundException)
    {
        return null;
    }

    // This takes 5 seconds if the computer is not on a domain
    using (var rootDe = new DirectoryEntry("LDAP://RootDSE"))
    {
        try
        {
            return (string)rootDe.Properties["defaultNamingContext"][0];
        }
        catch (COMException ex)
        {
            if (ex.ErrorCode == -2147023541)
                return null;
            throw;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多