У меня есть следующий код:
private static DirectorySearcher GetSearcher(string domain, string ouGroup)
{
var searchRoot = string.IsNullOrEmpty(ouGroup)
? new DirectoryEntry($"LDAP://{domain}")
: new DirectoryEntry($"LDAP://{domain}/{ouGroup}");
return new DirectorySearcher(searchRoot);
}
public IReadOnlyList<AdGroup> FilterGroupAndMemebers(string domain, string ouGroupDistinguishedName, string filter)
{
var result = new List<AdGroup>();
var childGroupTask = Task.Factory.StartNew(() => GetChildGroups(domain, ouGroupDistinguishedName, filter))
.ContinueWith(task => result.AddRange(task.Result));
var membersTask = Task.Factory.StartNew(() => GetMemberGroups(domain, ouGroupDistinguishedName, filter))
.ContinueWith(task => result.AddRange(task.Result));
Task.WaitAll(childGroupTask, membersTask);
return result;
}
public IReadOnlyList<AdGroup> GetMemberGroups(string domain, string ouGroupDistinguishedName, string filter)
{
using (var searcher = GetSearcher(domain, null))
{
searcher.Filter = $"(&(cn=*{filter.Trim()}*)(memberOf={ouGroupDistinguishedName}))";
searcher.Asynchronous = true;
searcher.PropertiesToLoad.Add("adspath");
searcher.PropertiesToLoad.Add("objectguid");
searcher.PropertiesToLoad.Add("cn");
searcher.PropertiesToLoad.Add("description");
searcher.PageSize = 150;
var searchResult = searcher.FindAll();
using (searchResult)
{
return searchResult
.OfType<SearchResult>()
.Select(group =>
{
return new AdGroup
{
Id = new Guid(group.Properties["objectguid"].OfType<byte[]>().First()),
Name = group.Properties["cn"].OfType<string>().FirstOrDefault(),
Description = group.Properties["description"].OfType<string>().FirstOrDefault(),
};
})
.ToList();
}
}
}
public IReadOnlyList<AdGroup> GetChildGroups(string domain, string ouGroupDistinguishedName, string filter)
{
using (var searcher = GetSearcher(domain, ouGroupDistinguishedName))
{
searcher.Filter = $"(&(cn=*{filter.Trim()}*)(objectclass=group))";
searcher.SearchScope = SearchScope.Subtree;
searcher.Asynchronous = true;
searcher.PropertiesToLoad.Add("adspath");
searcher.PropertiesToLoad.Add("objectguid");
searcher.PropertiesToLoad.Add("cn");
searcher.PropertiesToLoad.Add("description");
searcher.PageSize = 150;
var searchResult = searcher.FindAll();
using (searchResult)
{
return searchResult
.OfType<SearchResult>()
.Select(group =>
{
return new AdGroup
{
Id = new Guid(group.Properties["objectguid"].OfType<byte[]>().First()),
Name = group.Properties["cn"].OfType<string>().FirstOrDefault(),
Description = group.Properties["description"].OfType<string>().FirstOrDefault(),
};
})
.ToList();
}
}
}
Ссылка на снимок экрана:
https://ibb.co/cQJmnp
Итак, на прилагаемой картинке вы видите группу «Sales UK», и она является членом группы «Sales». «Sales UK» является дочерним предприятием «OU = Groups». У них разные значки, и я не совсем уверен, какая разница. Я называю их обоих "группами AD".
Группа "Продажи" находится в другой группе AD. «Sales UK» связан с «Sales» через атрибут «memberOf». Когда я ищу группу по CN, я хотел бы искать в группе всех детей плюс всех участников (связанных с атрибутом memberOf)
Если я введу фразу «Sa», я получу в результате «Sales» и «Sales UK». Сейчас я делаю два отдельных запроса. Мне интересно, есть ли возможность создать только один запрос и каким-то образом объединить эти фильтры.