我试图查询Active Directory并返回一个IEnumerable但是使用Title和EmailAddress这样的属性,这些属性没有显示在做PrincipalSearcher.Findll()。如果我使用PrincipalSearcher.FindOne(),它有更多的属性(但仍然不是标题),所以我试图找出我做的不同或者如何得到我需要的信息。谷歌试图找到更多信息已经疲惫不堪,看起来像UserPrincipal.GetUnderlyingObject()可能是票,但我不明白如何将其纳入foreach循环以便将其填入列表
public class ADUser
{
public string SamAccountName { get; set; }
public string DisplayName { get; set; }
public string Title { get; set; }
public IEnumerable<ADUser> Get(string username)
{
var users = new List<ADUser>();
var principalContext = new PrincipalContext(ContextType.Domain, "domain.com");
var userPrincipal = new UserPrincipal(principalContext)
{
SamAccountName = username
};
var principalSearcher = new PrincipalSearcher(userPrincipal);
foreach (var user in principalSearcher.FindAll())
{
users.Add(new ADUser
{
SamAccountName = user.SamAccountName,
DisplayName = user.DisplayName,
//Title = user.Title //Won't work, no Title property
});
}
return users;
}
}
这有效,但只返回.FindOne()所做的一小部分属性,但是如果我做了FindOne(),我就无法搜索部分用户名,例如&#34; jsm&#34 ;回归&#34;约翰史密斯&#34;和#34; James Smoth&#34;。
答案 0 :(得分:1)
简短的回答是你可以这样做:
foreach (var user in principalSearcher.FindAll())
{
var userDe = (DirectoryEntry) user.GetUnderlyingObject();
users.Add(new ADUser
{
SamAccountName = user.SamAccountName,
DisplayName = user.DisplayName,
Title = userDe.Properties["title"]?.Value.ToString()
});
}
这是我再也不使用AccountManagement
命名空间的部分原因了。它在后台使用DirectoryEntry
并隐藏其复杂性,以便让您更轻松地完成基本操作,但您仍需要直接使用DirectoryEntry
来处理某些事情。它实际上比直接使用DirectoryEntry
/ DirectorySearcher
要慢。
以下是您如何通过DirectorySearcher
执行相同操作的示例。这有点复杂,但我打赌你会发现它表现得更快:
public class ADUser
{
public string SamAccountName { get; set; }
public string DisplayName { get; set; }
public string Title { get; set; }
public IEnumerable<ADUser> Get(string username)
{
var users = new List<ADUser>();
var search = new DirectorySearcher(
new DirectoryEntry("LDAP://domain.com"),
$"(&(objectClass=user)(objectCategory=person)(sAMAccountName={username}))",
new [] { "sAMAccountName", "displayName", "title" } //The attributes you want to see
) {
PageSize = 1000 //If you're expecting more than 1000 results, you need this otherwise you'll only get the first 1000 and it'll stop
};
using (var results = search.FindAll()) {
foreach (SearchResult result in results)
{
users.Add(new ADUser
{
SamAccountName = result.Properties.Contains("sAMAccountName") ? result.Properties["sAMAccountName"][0].ToString() : null,
DisplayName = result.Properties.Contains("displayName") ? result.Properties["displayName"][0].ToString() : null,
Title = result.Properties.Contains("title") ? result.Properties["title"][0].ToString() : null
});
}
}
return users;
}
}