LDAP - 在 MemberOf 过滤器上使用通配符
LDAP - Use of wildcard on MemberOf filter
我需要从特定类别中获取所有用户及其组。
用户示例:
user | memberof
user1 | CN=group_1,OU=Groupes,OU=CR 1,DC=zcam,DC=ztech
user1 | CN=group_2,OU=Groupes,OU=CR 1,DC=zcam,DC=ztech
user2 | CN=group_2,OU=Groupes,OU=CR 1,DC=zcam,DC=ztech
user3 | CN=group_3,OU=Groupes,OU=CR 2,DC=zcam,DC=ztech
我需要获取 memberof
包含 OU=Groupes,OU=CR 1,DC=zcam,DC=ztech
的每个用户(我的示例中的 user1 和 user2)
按照此文档 (https://docs.microsoft.com/fr-fr/windows/desktop/ADSI/search-filter-syntax),我尝试了以下语法:
DirectoryEntry ldap = new DirectoryEntry("LDAP://xxx.xxx.xxx.xxx");
using (DirectorySearcher searcher = new DirectorySearcher(ldap))
{
// Works but return everything
searcher.Filter = "(&(objectClass=user)(memberof=*))";
// Works but only for one group
searcher.Filter = "(&(objectClass=user)(memberof=CN=group_1,OU=Groupes,OU=CR 1,DC=zcam,DC=ztechh))";
// Doesn't work because searcher.FindAll().Count returns 0
searcher.Filter = "(&(objectClass=user)(memberof=*,OU=Groupes,OU=CR 1,DC=zcam,DC=ztechh))";
// searcher.FindAll().Count returns 0
foreach (SearchResult result in searcher.FindAll())
{
[...]
}
在这 (https://community.servicenow.com/community?id=community_question&sys_id=00d29fa1db101fc01dcaf3231f96197f) 之后,我尝试将通配符 *
更改为 %
,但结果没有改变。
编辑版本;扩展所有 group_X
(
&(objectClass=user)
(|(memberof=CN=group_1,OU=Groupes,OU=CR 1,DC=zcam,DC=ztechh)
(memberof=CN=group_2,OU=Groupes,OU=CR 1,DC=zcam,DC=ztechh))
)
I need to get every user where memberof contains OU=Groupes,OU=CR 1,DC=zcam,DC=ztech (user1 and user2 from my example)
如果我没理解错的话,我认为这句话概括了您要尝试做的事情。您想要查找属于该 OU 中任何组的所有用户。
Active Directory 不允许您在任何带有 distinguishedName
的属性上使用通配符。这包括 member
和 memberOf
。所以唯一的方法是分两步:
- 找到该 OU 中所有组的
distinguishedName
。
- 搜索
memberOf
包含在步骤 1 中找到的值之一的所有用户。
类似这样的东西(我还没有针对 AD 测试它,所以你可能需要调整它):
var groupSearch = new DirectorySearcher(
new DirectoryEntry("LDAP://OU=Groupes,OU=CR 1,DC=zcam,DC=ztech"), //notice the OU
"(objectClass=group)");
//if you don't do this, it will return *every* attribute, which is slower
groupSearch.PropertiesToLoad.Add("distinguishedName");
//build a user query with all the groups
var userFilter = new StringBuilder("(&(objectClass=user)(|");
using (var results = groupSearch.FindAll()) {
foreach (SearchResult result in results) {
userFilter.Append($"(memberOf={result.Properties["distinguishedName"][0]})");
}
}
userFilter.Append(")");
var userSearch = new DirectorySearcher(
new DirectoryEntry("LDAP://DC=zcam,DC=ztech"),
userFilter.ToString());
//userSearch.PropertiesToLoad.Add(""); //add only the attributes you need to make it quicker
using (var results = userSearch.FindAll()) {
foreach (SearchResult result in results) {
//do something
}
}
请注意,这只会找到这些组的 直接 成员。它不会 return 嵌套组中的用户(当用户所在的组是这些组之一的成员时)。如果需要,您可以调整过滤器以包含一个特殊标志,告诉 AD 递归搜索:
userFilter.Append($"(memberOf:1.2.840.113556.1.4.1941:={result.Properties["distinguishedName"][0]})");
根据您的域,您可能需要了解两件事:
- 这不会 return 将这些组之一作为其主要组的用户,因为该关系不使用
member
/memberOf
存储。
- 如果这些组有来自外部受信任域的成员,那么您最终会找到外部安全主体对象,而不是它们的实际用户对象。如果这对您来说是个问题,那就完全是另外一回事了。
如果您好奇的话,我已经写了几篇关于这个主题的文章。从这个开始:Active Directory: What makes a member a member?
终于找到另一种方法了。
其实memberof
中的这个属性OU=CR 1
对应的就是我AD中的分区。
所以我只是像这样过滤:
DirectoryEntry ldap = new DirectoryEntry("LDAP://xxx.xxx.xxx.xxx");
using (DirectorySearcher searcher = new DirectorySearcher(ldap))
{
searcher.Filter = "(&(objectClass=user)(division=CR 1))";
foreach (SearchResult result in searcher.FindAll())
{
[...]
}
感谢大家的帮助。
我需要从特定类别中获取所有用户及其组。
用户示例:
user | memberof
user1 | CN=group_1,OU=Groupes,OU=CR 1,DC=zcam,DC=ztech
user1 | CN=group_2,OU=Groupes,OU=CR 1,DC=zcam,DC=ztech
user2 | CN=group_2,OU=Groupes,OU=CR 1,DC=zcam,DC=ztech
user3 | CN=group_3,OU=Groupes,OU=CR 2,DC=zcam,DC=ztech
我需要获取 memberof
包含 OU=Groupes,OU=CR 1,DC=zcam,DC=ztech
的每个用户(我的示例中的 user1 和 user2)
按照此文档 (https://docs.microsoft.com/fr-fr/windows/desktop/ADSI/search-filter-syntax),我尝试了以下语法:
DirectoryEntry ldap = new DirectoryEntry("LDAP://xxx.xxx.xxx.xxx");
using (DirectorySearcher searcher = new DirectorySearcher(ldap))
{
// Works but return everything
searcher.Filter = "(&(objectClass=user)(memberof=*))";
// Works but only for one group
searcher.Filter = "(&(objectClass=user)(memberof=CN=group_1,OU=Groupes,OU=CR 1,DC=zcam,DC=ztechh))";
// Doesn't work because searcher.FindAll().Count returns 0
searcher.Filter = "(&(objectClass=user)(memberof=*,OU=Groupes,OU=CR 1,DC=zcam,DC=ztechh))";
// searcher.FindAll().Count returns 0
foreach (SearchResult result in searcher.FindAll())
{
[...]
}
在这 (https://community.servicenow.com/community?id=community_question&sys_id=00d29fa1db101fc01dcaf3231f96197f) 之后,我尝试将通配符 *
更改为 %
,但结果没有改变。
编辑版本;扩展所有 group_X
(
&(objectClass=user)
(|(memberof=CN=group_1,OU=Groupes,OU=CR 1,DC=zcam,DC=ztechh)
(memberof=CN=group_2,OU=Groupes,OU=CR 1,DC=zcam,DC=ztechh))
)
I need to get every user where memberof contains OU=Groupes,OU=CR 1,DC=zcam,DC=ztech (user1 and user2 from my example)
如果我没理解错的话,我认为这句话概括了您要尝试做的事情。您想要查找属于该 OU 中任何组的所有用户。
Active Directory 不允许您在任何带有 distinguishedName
的属性上使用通配符。这包括 member
和 memberOf
。所以唯一的方法是分两步:
- 找到该 OU 中所有组的
distinguishedName
。 - 搜索
memberOf
包含在步骤 1 中找到的值之一的所有用户。
类似这样的东西(我还没有针对 AD 测试它,所以你可能需要调整它):
var groupSearch = new DirectorySearcher(
new DirectoryEntry("LDAP://OU=Groupes,OU=CR 1,DC=zcam,DC=ztech"), //notice the OU
"(objectClass=group)");
//if you don't do this, it will return *every* attribute, which is slower
groupSearch.PropertiesToLoad.Add("distinguishedName");
//build a user query with all the groups
var userFilter = new StringBuilder("(&(objectClass=user)(|");
using (var results = groupSearch.FindAll()) {
foreach (SearchResult result in results) {
userFilter.Append($"(memberOf={result.Properties["distinguishedName"][0]})");
}
}
userFilter.Append(")");
var userSearch = new DirectorySearcher(
new DirectoryEntry("LDAP://DC=zcam,DC=ztech"),
userFilter.ToString());
//userSearch.PropertiesToLoad.Add(""); //add only the attributes you need to make it quicker
using (var results = userSearch.FindAll()) {
foreach (SearchResult result in results) {
//do something
}
}
请注意,这只会找到这些组的 直接 成员。它不会 return 嵌套组中的用户(当用户所在的组是这些组之一的成员时)。如果需要,您可以调整过滤器以包含一个特殊标志,告诉 AD 递归搜索:
userFilter.Append($"(memberOf:1.2.840.113556.1.4.1941:={result.Properties["distinguishedName"][0]})");
根据您的域,您可能需要了解两件事:
- 这不会 return 将这些组之一作为其主要组的用户,因为该关系不使用
member
/memberOf
存储。 - 如果这些组有来自外部受信任域的成员,那么您最终会找到外部安全主体对象,而不是它们的实际用户对象。如果这对您来说是个问题,那就完全是另外一回事了。
如果您好奇的话,我已经写了几篇关于这个主题的文章。从这个开始:Active Directory: What makes a member a member?
终于找到另一种方法了。
其实memberof
中的这个属性OU=CR 1
对应的就是我AD中的分区。
所以我只是像这样过滤:
DirectoryEntry ldap = new DirectoryEntry("LDAP://xxx.xxx.xxx.xxx");
using (DirectorySearcher searcher = new DirectorySearcher(ldap))
{
searcher.Filter = "(&(objectClass=user)(division=CR 1))";
foreach (SearchResult result in searcher.FindAll())
{
[...]
}
感谢大家的帮助。