C# 如何从 Active Directory 中检索 SAMAccountName

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10112062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 12:28:47  来源:igfitidea点击:

How to retrieve SAMAccountName from Active Directory

c#active-directorydirectoryservices

提问by unknownUser

I implemented a method that returns a list of Active Directory users, I would like to retrieve SAMAccountName like this Domain\Administrator.

我实现了一个返回 Active Directory 用户列表的方法,我想像这样检索 SAMAccountName Domain\Administrator

This is the method I use:

这是我使用的方法:

public Collection<software_user> GetUsersFromAD(String adConnectionString)
{
    var users = new Collection<software_user>();

    using (var directoryEntry = new DirectoryEntry(adConnectionString))
    {
        var directorySearcher = new DirectorySearcher(directoryEntry);
        directorySearcher.Filter = "(&(objectClass=user))";
        var propertiesToLoad = new[] 
        { 
           "SAMAccountName", 
           "displayName", 
           "givenName", 
           "sn", 
           "mail", 
           "userAccountControl", 
           "objectSid" 
        };
        directorySearcher.PropertiesToLoad.AddRange(propertiesToLoad);

        foreach (SearchResult searchEntry in directorySearcher.FindAll())
        {
            var userEntry = searchEntry.GetDirectoryEntry();
            var ldapUser = new software_user();
            ldapUser.User_name = NullHandler.GetString(userEntry.Properties["displayName"].Value);

            if (string.IsNullOrEmpty(ldapUser.User_name))
               continue;
            ldapUser.User_name = NullHandler.GetString(userEntry.Properties["SAMAccountName"].Value);
            ldapUser.email = NullHandler.GetString(userEntry.Properties["mail"].Value);
            ldapUser.user_shortname = NullHandler.GetString(userEntry.Properties["givenName"].Value);
            var userAccountControl = (int)userEntry.Properties["userAccountControl"].Value;
            //ldapUser.IsActive = (userAccountControl & UF_ACCOUNTDISABLE) != UF_ACCOUNTDISABLE;
            var sid = new SecurityIdentifier((byte[])userEntry.Properties["objectSid"][0], 0).Value;
            //ldapUser.SId = sid;
            users.Add(ldapUser);
         }
    }
    return users;
}

回答by marc_s

First off:Domain\Administratoris NOTa SAM account name! The SAM account name is a unique (over the whole domain) name of up to 20 characters in length - typically it's your "Windows user name" (e.g. Administrator) - but it does NOTinclude the domain name. That value made up of domain\usernameis NOTstored in Active Directory anywhere!

第一关:Domain\Administrator不是一个SAM帐户名!SAM帐户名是唯一的(在整个域)最多20个字符长的名字-通常这是你的“Windows用户名”(例如Administrator) -但它包括域名。组成的domain\username不会存储在 Active Directory 中的任何地方!



If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement(S.DS.AM) namespace. Read all about it here:

如果您使用 .NET 3.5 及更高版本,则应查看System.DirectoryServices.AccountManagement(S.DS.AM) 命名空间。在这里阅读所有相关信息:

Basically, you can define a domain context and easily find users and/or groups in AD:

基本上,您可以定义域上下文并轻松找到 AD 中的用户和/或组:

// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");

if(user != null)
{
   // do something here....     
   string samAccountName = user.SamAccountName;
}

The new S.DS.AM makes it really easy to play around with users and groups in AD!

新的 S.DS.AM 使在 AD 中与用户和组一起玩变得非常容易!

If you want to search for a whole group of users (or groups or computers), you can use a PrincipalSearcherand a "query-by-example" principal to do your searching:

如果要搜索整个用户组(或组或计算机),可以使用 aPrincipalSearcher和“query-by-example”主体进行搜索:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the last name (Surname) of "Miller"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.Surname = "Miller";

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// find all matches
foreach(var found in srch.FindAll())
{
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....          
}

回答by Christopher G. Lewis

You can translate a user as a Distinguished name to DOMAIN\SAMaccount form using the Object's SID, and the System.Security.Principal.SecurityIdentifier.Translate command.

您可以使用对象的 SID 和 System.Security.Principal.SecurityIdentifier.Translate 命令将用户作为专有名称转换为 DOMAIN\SAMaccount 形式。

public Collection<software_user> GetUsersFromAD(String adConnectionString)
    {
            var users = new Collection<software_user>();

            using (var directoryEntry = new DirectoryEntry(adConnectionString))
            {
                    var directorySearcher = new DirectorySearcher(directoryEntry);
                    directorySearcher.Filter = "(&(objectClass=user))";
                    var propertiesToLoad = new[] 
                    { 
                         "SAMAccountName", 
                         "displayName", 
                         "givenName", 
                         "sn", 
                         "mail", 
                         "userAccountControl", 
                         "objectSid" 
                    };
                    directorySearcher.PropertiesToLoad.AddRange(propertiesToLoad);

                    foreach (SearchResult searchEntry in directorySearcher.FindAll())
                    {
                            var userEntry = searchEntry.GetDirectoryEntry();
                            var ldapUser = new software_user();
                            ldapUser.User_name = NullHandler.GetString(userEntry.Properties["displayName"].Value);

                            if (string.IsNullOrEmpty(ldapUser.User_name))
                                 continue;
                            ldapUser.User_name = NullHandler.GetString(userEntry.Properties["SAMAccountName"].Value);
                            ldapUser.email = NullHandler.GetString(userEntry.Properties["mail"].Value);
                            ldapUser.user_shortname = NullHandler.GetString(userEntry.Properties["givenName"].Value);
                            var userAccountControl = (int)userEntry.Properties["userAccountControl"].Value;

                            //ldapUser.IsActive = (userAccountControl & UF_ACCOUNTDISABLE) != UF_ACCOUNTDISABLE;
                            SecurityIdentifier sid = new SecurityIdentifier((byte[])userEntry.Properties["objectSid"][0], 0).Value;
    -->                     NTAccount account = (NTAccount) sid.Translate(typeof(NTAccount));
    -->                     ldapUser.User_name = account.ToString();

                            //ldapUser.SId = sid;
                            users.Add(ldapUser);
                     }
            }
            return users;
    }