我确信有一个非常简单的解释,但我找不到它。我正在尝试计算我们域中所有组的成员数,并且下面的代码大部分都可用,但是有一个特定的组我无法准确计算。该组有超过1000名成员,但由于某种原因,下面的代码保持返回0.这是由于成员的数量?该集团没有什么特别之处,它只是一个普通的全球安全组织。
DirectoryEntry context = new DirectoryEntry("LDAP://MyDomain.test");
DirectorySearcher searchGroups = new DirectorySearcher(context);
searchGroups.SearchScope = SearchScope.Subtree;
searchGroups.PageSize = 500;
searchGroups.Filter = "objectClass=group";
searchGroups.PropertiesToLoad.Add("member");
SearchResultCollection searchGroupsResults = searchGroups.FindAll();
foreach (SearchResult group in searchGroupsResults)
{
Console.WriteLine("Group: " + group.Properties["name"][0].ToString() + " - Member Count: " + group.Properties["member"].Count.ToString());
}
返回:
组:MyGroup1 - 成员数:0
组:MyGroup2 - 成员人数:861
组:MyGroup3 - 成员人数:920
组:MyGroup4 - 会员数:9 ....
答案 0 :(得分:1)
如果你查询一个大组,并且微软在C ++中演示了一个复杂的算法,那就复杂得多了,
https://msdn.microsoft.com/en-us/library/aa367017(v=vs.85).aspx
有人翻译成.NET
https://itconnect.uw.edu/wares/msinf/authn/ldap/enumerate-large-groups/
...
using System.DirectoryServices;
...
/// <summary>
/// Determines whether or not the specified user is a member of the group.
/// </summary>
/// <param name="UserDN">A System.String containing the user's distinguished name (DN).</param>
/// <param name="Group">A System.DirectoryServices.DirectoryEntry object of the target group.</param>
private Boolean IsMemberOfLargeGroup( String UserDN, DirectoryEntry Group )
{
Boolean userFound = false;
Boolean isLastQuery = false;
Boolean exitLoop = false;
Int32 rangeStep = 1500;
Int32 rangeLow = 0;
Int32 rangeHigh = rangeLow + ( rangeStep - 1 );
String attributeWithRange;
DirectorySearcher groupSearch = new DirectorySearcher( Group );
SearchResult searchResults;
groupSearch.Filter = "(objectClass=*)";
do
{
if( !isLastQuery )
attributeWithRange = String.Format( "member;range={0}-{1}", rangeLow, rangeHigh );
else
attributeWithRange = String.Format( "member;range={0}-*", rangeLow );
groupSearch.PropertiesToLoad.Clear();
groupSearch.PropertiesToLoad.Add( attributeWithRange );
searchResults = groupSearch.FindOne();
groupSearch.Dispose();
if( searchResults.Properties.Contains( attributeWithRange ) )
{
if( searchResults.Properties[ attributeWithRange ].Contains( userDN ) )
userFound = true;
if( isLastQuery )
exitLoop = true;
}
else
{
isLastQuery = true;
}
if( !isLastQuery )
{
rangeLow = rangeHigh + 1;
rangeHigh = rangeLow + ( rangeStep - 1 );
}
}
while( ! ( exitLoop | userFound ) );
return userFound;
}
答案 1 :(得分:0)
可能是由于您的searchGroups
在收集垃圾时无法释放所有非托管资源,如msnd所述:https://msdn.microsoft.com/en-us/library/system.directoryservices.directorysearcher.findall.aspx
尝试在使用中包装所有内容,或使用Dispose():
using SearchResultCollection searchGroupsResults = searchGroups.FindAll())
{
foreach (SearchResult group in searchGroupsResults)
{
Console.WriteLine("Group: " + group.Properties["name"][0].ToString() + " - Member Count: " + group.Properties["member"].Count.ToString());
}
}
答案 2 :(得分:0)
谢谢你的帮助。我按照你的建议做了并使用了Dispose()方法,但它没有帮助。我能够通过使用DirectoryEntry而不是SearchResult解决问题。见下文。
DirectoryEntry context = new DirectoryEntry("LDAP://My.Domain.com");
DirectorySearcher searchGroups = new DirectorySearcher(context);
searchGroups.SearchScope = SearchScope.Subtree;
searchGroups.PageSize = 500;
searchGroups.Filter = "objectClass=group";
searchGroups.PropertiesToLoad.Add("name");
searchGroups.PropertiesToLoad.Add("member");
SearchResultCollection searchGroupsResults = searchGroups.FindAll();
foreach (SearchResult group in searchGroupsResults)
{
DirectoryEntry groupDirectoryEntry = group.GetDirectoryEntry();
Console.WriteLine("Group: " + group.Properties["name"][0].ToString() + " - Member Count: " + groupDirectoryEntry.Properties["member"].Count.ToString());
}