[英]How can I get a list of Active Directory Users (Only the Users that appear in the windows Logon Screen)
[英]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 查詢。 您可以使用的DirectorySearcher從System.DirectoryServices
或SearchRequest從System.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 Name
而sn
將為您提供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.