我创建了一个dot.net表单,该表单使用c#代码检索用户从下拉列表中选择的Active Directory组的成员,然后在网页上显示成员列表(用户就是我想要的)。
这对于不包含子组的组很好用。当Active Directory组包含用户和子组时,我会收到一条错误消息。
我只希望用户从下拉列表中选择的组的用户。我不要来自任何分组的用户。
我已经在互联网上进行了大量搜索并测试了各种代码建议。
public List<string> GetAllUsersFromGroup(string domain,
string group)
{
List<string> retVal = new List<string>();
DirectoryEntry entry = new DirectoryEntry(domain);
DirectorySearcher searcher = new DirectorySearcher("
(&(objectCategory=Group)(cn=" + group + "))");
searcher.SearchRoot = entry;
searcher.SearchScope = SearchScope.Subtree;
SearchResult result = searcher.FindOne();
var x = 0;
var txtCN = "";
var txtDispName = "";
var firstItem = 0; // Display Name
var secondItem = 1; // CN
var arraryResultsSize = result.Properties["member"].Count;
string[] deResultsArray = new string[arraryResultsSize];
foreach (string member in result.Properties["member"])
{
DirectoryEntry de = new DirectoryEntry(String.Concat(domain,
"/", member.ToString()));
if (de.Properties["objectClass"].Contains("user") &&
de.Properties["cn"].Count > 0)
{
deResultsArray[x] = de.Properties["displayName"]
[0].ToString() + "~" + de.Properties["cn"]
[0].ToString();
}
x = x + 1;
}
if (deResultsArray[0] != null) {
string[] sortSeperatedItems = sortLDAPUsers(deResultsArray);
for (var i = 0; i < sortSeperatedItems.Length/2; i++) {
txtDispName = "<tr><td>" + sortSeperatedItems[firstItem]
+ "</td>";
txtCN = "<td>" + sortSeperatedItems[secondItem] + "</td>
</tr>";
retVal.Add(txtDispName);
retVal.Add(txtCN);
firstItem = firstItem + 2;
secondItem = secondItem + 2;
}
} else {
txtDispName = "<tr><td>Group has no members</td>";
txtCN = "<td> </td></tr>";
retVal.Add(txtDispName);
retVal.Add(txtCN);
}
// retVal.Add("Array Size is: " + propCount);
return retVal;
}
public string[] sortLDAPUsers(string[] strArray) {
Array.Sort(strArray);
var newArraySize = (strArray.Length * 2);
string[] itemSeperated = new string[2];
string[] allSepItems = new string[newArraySize];
var arrayItemsString = "";
var xDName = 0;
var xCName = 1;
for (var i = 0; i < strArray.Length; i++) {
itemSeperated = strArray[i].Split('~');
allSepItems[xDName] = itemSeperated[0];
allSepItems[xCName] = itemSeperated[1];
arrayItemsString = arrayItemsString + "Length of allSepItems
is: " + allSepItems.Length + " Text is: " +
allSepItems[xDName] + " NetId is: " + allSepItems[xCName] +
"<br><br>";
xDName = xDName + 2;
xCName = xCName + 2;
}
return allSepItems;
}
当用户选择包含用户和子组的Active Directory组时,出现以下错误:
异常详细信息:System.NullReferenceException:对象引用未设置为对象的实例。
源错误:
Line 205: for (var i = 0; i < strArray.Length; i++) {
Line 206:
Line 207: itemSeperated = strArray[i].Split('~');
Line 208: allSepItems[xDName] = itemSeperated[0];
Line 209: allSepItems[xCName] = itemSeperated[1];
我认为错误与我在GetAllUsersFromGroup()中过滤或获取结果的方式有关。我不知道如何仅从组中吸引用户,而在结果中不包括任何子组。
答案 0 :(得分:0)
此过滤器(&(objectCategory=Group)(cn=<group>))
的问题在于,您正在查询特定的 group 以迭代并抓住所有成员,而与类型/ objectClass无关,因此您将获得用户,组和其他任何内容。
相反,您可以使用适当的过滤器直接请求属于该组的用户:
new DirectorySearcher("(&(objectCategory=person)(memberOf=" + groupDN + "))");
请注意,memberOf
属性必须与DN匹配,因此给定传入的变量group
(如果调用者无法传递实际的组dn),则可能必须先捕获它使用第一个过滤器放置。
随后出现的错误是由于排序而引起的另一个问题,请注释此部分,直到获得正确的结果为止。
答案 1 :(得分:-1)
当您可以让Microsoft Active Directory完成工作时,您不需要那么努力。
带有LDAP过滤器的LDAP搜索请求,过滤条件为Resolve all members (including nested) Security Groups (requires at least Windows 2003 SP2)
(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=Security Groups,OU=Groups,DC=YOURDOMAIN,DC=NET)
这将返回所有“ GroupOne”成员的(objectClass = user)。