簡體   English   中英

如何從活動目錄中獲取用戶列表?

[英]How can I get a list of users from active directory?

如何從活動目錄中獲取用戶列表? 有沒有辦法提取用戶名,名字,姓氏? 我看到了一個類似的帖子,其中使用了這個:

 PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN");

我從未對活動目錄做過任何事情,所以我完全迷失了。 任何幫助將不勝感激!

如果您不熟悉 Active Directory,我建議您首先了解 Active Directory 如何存儲數據。

Active Directory 實際上是一個 LDAP 服務器。 存儲在 LDAP 服務器中的對象是分層存儲的。 這與您將文件存儲在文件系統中非常相似。 這就是為什么它有名稱目錄服務器和活動目錄

Active Directory 上的容器和對象可以通過distinguished name指定。 專有名稱是這樣的CN=SomeName,CN=SomeDirectory,DC=yourdomain,DC=com 與傳統的關系數據庫一樣,您可以對 LDAP 服務器運行查詢。 這稱為 LDAP 查詢。

有多種方法可以在 .NET 中運行 LDAP 查詢。 您可以使用的DirectorySearcherSystem.DirectoryServicesSearchRequestSystem.DirectoryServices.Protocol

對於您的問題,由於您要求專門查找用戶主體對象,我認為最直觀的方法是使用System.DirectoryServices.AccountManagement PrincipalSearcher 你可以很容易地從谷歌找到很多不同的例子。 這是一個完全符合您要求的示例。

using (var context = new PrincipalContext(ContextType.Domain, "yourdomain.com"))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        foreach (var result in searcher.FindAll())
        {
            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
            Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
            Console.WriteLine("Last Name : " + de.Properties["sn"].Value);
            Console.WriteLine("SAM account name   : " + de.Properties["samAccountName"].Value);
            Console.WriteLine("User principal name: " + de.Properties["userPrincipalName"].Value);
            Console.WriteLine();
        }
    }
}
Console.ReadLine();

請注意,在 AD 用戶對象上,有許多屬性。 特別是, givenName將為您提供First Namesn將為您提供Last Name 關於用戶名。 我想你的意思是用戶登錄名。 請注意,AD 用戶對象上有兩個登錄名。 一種是samAccountName ,也稱為 Windows 2000 之前的用戶登錄名。 userPrincipalName通常在 Windows 2000 之后使用。

如果要過濾 y 個活動帳戶,請將其添加到Harvey 的代碼中

 UserPrincipal userPrin = new UserPrincipal(context);
 userPrin.Enabled = true;

第一次使用后。 然后加

  searcher.QueryFilter = userPrin;

在找到所有之前。 這應該會讓你成為活躍的人。

用於瀏覽 AD 的 PrincipalContext 非常慢(僅用於 .ValidateCredentials,見下文),使用 DirectoryEntry 和 .PropertiesToLoad() 這樣您只需為您需要的內容付費。

此處的過濾器和語法: https : //social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx

此處的屬性: https : //docs.microsoft.com/en-us/windows/win32/adschema/attributes-all

using (var root = new DirectoryEntry($"LDAP://{Domain}"))
{
    using (var searcher = new DirectorySearcher(root))
    {
        // looking for a specific user
        searcher.Filter = $"(&(objectCategory=person)(objectClass=user)(sAMAccountName={username}))";
        // I only care about what groups the user is a memberOf
        searcher.PropertiesToLoad.Add("memberOf");

        // FYI, non-null results means the user was found
        var results = searcher.FindOne();

        var properties = results?.Properties;
        if (properties?.Contains("memberOf") == true)
        {
            // ... iterate over all the groups the user is a member of
        }
    }
}

干凈,簡單,快速。 沒有魔法,也沒有對 .RefreshCache 的半記錄調用以在 try/catch 中獲取 tokenGroups 或 .Bind 或 .NativeObject 以驗證憑據。

用於驗證用戶:

using (var context = new PrincipalContext(ContextType.Domain))
{
    return context.ValidateCredentials(username, password);
}

當然,功勞歸於@Harvey Kwok 這里,但我只是想添加這個例子,因為在我的情況下,我想獲得一個實際的 UserPrincipals 列表。 預先過濾此查詢可能更有效,但在我的小環境中,提取所有內容然后根據需要從我的列表中進行過濾會更容易。

根據您的需要,您可能不需要強制轉換為 DirectoryEntry,但某些屬性在 UserPrincipal 中不可用。

using (var searcher = new PrincipalSearcher(new UserPrincipal(new PrincipalContext(ContextType.Domain, Environment.UserDomainName))))
{
    List<UserPrincipal> users = searcher.FindAll().Select(u => (UserPrincipal)u).ToList();
    foreach(var u in users)
        {
            DirectoryEntry d = (DirectoryEntry)u.GetUnderlyingObject();
            Console.WriteLine(d.Properties["GivenName"]?.Value?.ToString() + d.Properties["sn"]?.Value?.ToString());
        }
}

包含 System.DirectoryServices.dll,然后使用以下代碼:

DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + Environment.MachineName);
string userNames="Users: ";

foreach (DirectoryEntry child in directoryEntry.Children)
{
    if (child.SchemaClassName == "User")
    {
        userNames += child.Name + Environment.NewLine   ;         
    }

}
MessageBox.Show(userNames);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM