我有搜索部门中所有用户的代码:
string Department = "Billing";
DirectorySearcher LdapSearcher = new DirectorySearcher();
LdapSearcher.PropertiesToLoad.Add("displayName");
LdapSearcher.PropertiesToLoad.Add("cn");
LdapSearcher.PropertiesToLoad.Add("department");
LdapSearcher.PropertiesToLoad.Add("title");
LdapSearcher.PropertiesToLoad.Add("memberOf");
LdapSearcher.Filter = string.Format("(&(objectClass=user)(department={0}))", Department);
SearchResultCollection src = LdapSearcher.FindAll();
如果我只想要“经理只读”AD组中的每个人,过滤器需要看起来怎么样?
我是不是错了?
答案 0 :(得分:34)
看看你的搜索,我有几个要点。首先,搜索使用objectClass(非索引)而不是objectCategory(索引)。该查询存在巨大的性能问题。你总是希望根据你想要检索的内容将两者结合起来:
(&(objectCategory=person)(objectClass=user)) = All users (no contacts)
(&(objectCategory=person)(objectClass=contact)) = All contacts (no users)
(&(objectCategory=person)) = All users and contacts
对于查找组中的用户,您可以枚举特定组的成员对象列表。在group对象的member属性中是每个用户的distinguishedName。
This article describes enumerating members of a group...
不要忘记您可能必须处理父组的嵌套组,因为没有使用LDAP查询处理此方法的默认方法。为此,您可能需要评估成员对象是否为组,然后获取该子组的成员属性。
最后,您应该养成为查询指定dns前缀的习惯。
没有DNS前缀:
LDAP://ou=ouname,dc=domain,dc=com
使用DNS前缀(全部三个工作):
LDAP://servername/ou=ouname,dc=domain,dc=com
LDAP://servername.domain.com/ou=ouname,dc=domain,dc=com
LDAP://domain.com/ou=ouname,dc=domain,dc=com
单个域不会给您带来太多问题,但是当您尝试在多域环境中运行搜索时,如果没有此添加,您将被咬住。希望这有助于使您更接近目标。
答案 1 :(得分:11)
我总是发现Howto: (Almost) Everything In Active Directory via C#有助于解决大多数AD问题。
答案 2 :(得分:6)
如果你知道该组的AD路径,那么打开一个DirectoryEntry可能会更容易,然后从那里做一个DirectorySearcher。
using (DirectoryEntry de = new DirectoryEntry("LDAP://somedomain/CN=FooBar"))
{
DirectorySearcher search = new DirectorySearcher(de, ("(objectClass=user)"));
}
Searcher上还有一个标志,表示是否要钻到子容器,我忘了手边的名字。
答案 3 :(得分:3)
IList<string> getMembers(string domainName, string groupName)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName);
if (grp == null) {
throw new ApplicationException("We did not find that group in that domain, perhaps the group resides in a different domain?");
}
IList<string> members = new List<String>();
foreach (Principal p in grp.GetMembers(true))
{
members.Add(p.Name); //You can add more attributes, samaccountname, UPN, DN, object type, etc...
}
grp.Dispose();
ctx.Dispose();
return members;
}
答案 4 :(得分:0)
//Search for Group and list group members
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices.AccountManagement;
namespace ExportActiveDirectoryGroupsUsers
{
class Program
{
static void Main(string[] args)
{
if (args == null)
{
Console.WriteLine("args is null, useage: ExportActiveDirectoryGroupsUsers OutputPath"); // Check for null array
}
else
{
Console.Write("args length is ");
Console.WriteLine(args.Length); // Write array length
for (int i = 0; i < args.Length; i++) // Loop through array
{
string argument = args[i];
Console.Write("args index ");
Console.Write(i); // Write index
Console.Write(" is [");
Console.Write(argument); // Write string
Console.WriteLine("]");
}
try
{
using (var ServerContext = new PrincipalContext(ContextType.Domain, ServerAddress, Username, Password))
{
/// define a "query-by-example" principal - here, we search for a GroupPrincipal
GroupPrincipal qbeGroup = new GroupPrincipal(ServerContext, args[0]);
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeGroup);
// find all matches
foreach (var found in srch.FindAll())
{
GroupPrincipal foundGroup = found as GroupPrincipal;
if (foundGroup != null)
{
// iterate over members
foreach (Principal p in foundGroup.GetMembers())
{
Console.WriteLine("{0}|{1}", foundGroup.Name, p.DisplayName);
// do whatever you need to do to those members
}
}
}
}
//Console.WriteLine("end");
}
catch (Exception ex)
{
Console.WriteLine("Something wrong happened in the AD Query module: " + ex.ToString());
}
Console.ReadLine();
}
}
}
}