检索大型AD组的所有成员

时间:2014-03-12 14:50:53

标签: active-directory ldap unboundid-ldap-sdk

使用Microsoft Active Directory和Unboundid SDK,并且有一个包含> 29k成员的组。

我正在尝试使用范围值来获取所有组,但无法确定何时到达目的地。

我正在使用此方法:(已更新为工作代码)

  public static List<String> getAttributeRangeBasedSearch(LDAPConnection ldc, String basedn, String filter, int step, String return_attribute) throws LDAPException
{
List<String> allValues = new ArrayList<String>();
// initialize counter to total the group members and range values
int allvalues = 0;
int start = 0;
// int step = 1000;
int finish = step - 1;
boolean finallyFinished = false;
String range;
// loop through the query until we have all the results
while (!finallyFinished)
{
    range = start + "-" + finish;
    String currentRange = return_attribute + ";Range=" + range;
    String range_returnedAtts[] = { currentRange };
    SearchRequest searchRequest = new SearchRequest(basedn, SearchScope.BASE, filter, range_returnedAtts);
    List<SearchResultEntry> rangedEntries = ldc.search(searchRequest).getSearchEntries();
    for (Iterator<SearchResultEntry> iterator = rangedEntries.iterator(); iterator.hasNext();)
    {
    SearchResultEntry searchResultEntry = iterator.next();
    Collection<Attribute> allAttribute = searchResultEntry.getAttributes();
    for (Iterator<Attribute> attributeIterator = allAttribute.iterator(); attributeIterator.hasNext();)
    {
        Attribute attribute = attributeIterator.next();
        log.debug("---> " + allvalues + ": " + attribute.getName());
        if (attribute.getName().endsWith("*"))
        {
        currentRange = attribute.getName();
        finallyFinished = true;
        }
        String[] attributeBatch = searchResultEntry.getAttributeValues(currentRange);
        for (int i = 0; i < attributeBatch.length; i++)
        {
        allValues.add(attributeBatch[i]);
        log.debug("-- " + allvalues++ + " " + attribute.getName() + ":" + attributeBatch[i]);
        }
    }

    }// for SearchResultEntry
    start = start + step;
    finish = finish + step;
}// finallyFinished
return allValues;
}

有什么想法吗?

由于 -Jim

3 个答案:

答案 0 :(得分:2)

我让事情有效,但是这个过程非常困难,目前我正在使用硬编码值,因为这可以动态更改,默认值为1,500,硬编码限制为5,000.

我无法动态确定值。 Appears, maybe,如果未在以下位置定义:CN =查询策略,CN =目录服务,CN = Windows NT,CN =服务,CN =配置,那么林根必须是默认值,默认情况下,也会因使用的Microsoft Active Directory版本而异。

MSDN中还介绍了可能有用的some sort of control,但没有关于如何使用它的信息。 有人使用过这个吗?

答案 1 :(得分:0)

这个可以在文本文件中检索和存储任意数量的用户。此外,如果组为空,它将无法在无限循环中完成

$myGroup = [string]$args[0];
$myGroup = $myGroup.replace(" ",",");
$group = [adsi]("LDAP://$($myGroup)");
$from = 0 
$all = $false 

$members = @() 


while (! $all) { 
   trap{$script:all = $True;continue} 
   $to = $from + 999 
   $DS = New-Object DirectoryServices.DirectorySearcher($Group,"(objectClass=*)","member;range=$from-$to",'Base') 
   $members += $ds.findall() | foreach {$_.properties | foreach {$_.item($_.PropertyNames -like 'member;*')}} 
   if($from -gt $members.count){
      break;
   }
   $from += 1000 
} 

$currentExecuting = (Get-Item $MyInvocation.MyCommand.Path)
$group.sAMAccountName
$members | measure-object 

$members > "$($currentExecuting.Directory)\$($group.sAMAccountName).txt"

用法:

getADGroupMembers.ps1 CN=groupName,OU=myOrgUnit,DC=contoso,DC=com

答案 2 :(得分:0)

这是一个非常好的代码示例,您可以在其中按范围获取组的所有成员。当您在最后一个范围内时,它也会处理这种情况。您还可以在分页请求中转换此方法。看一看。它帮助了我。

try
{
    DirectoryEntry entry = new DirectoryEntry("LDAP://CN=My Distribution List,OU=Distribution Lists,DC=Fabrikam,DC=com");
    DirectorySearcher searcher = new DirectorySearcher(entry);
    searcher.Filter = "(objectClass=*)";

    uint rangeStep = 1000;
    uint rangeLow = 0;
    uint rangeHigh = rangeLow + (rangeStep - 1);
    bool lastQuery = false;
    bool quitLoop = false;

    do
    {
        string attributeWithRange;
        if(!lastQuery)
        {
            attributeWithRange = String.Format("member;range={0}-{1}", rangeLow, rangeHigh);
    }
        else
        {
            attributeWithRange = String.Format("member;range={0}-*", rangeLow);
    }        
        searcher.PropertiesToLoad.Clear();
        searcher.PropertiesToLoad.Add(attributeWithRange);
        SearchResult results = searcher.FindOne();
        foreach(string res in results.Properties.PropertyNames)
        {
            System.Diagnostics.Debug.WriteLine(res.ToString());
    }
        if(results.Properties.Contains(attributeWithRange))
        {
            foreach(object obj in results.Properties[attributeWithRange])
            {
                Console.WriteLine(obj.GetType());
                if(obj.GetType().Equals(typeof(System.String)))
                {
            }
                else if (obj.GetType().Equals(typeof(System.Int32)))
                {
            }
                Console.WriteLine(obj.ToString());
        }
            if(lastQuery)
            {
                quitLoop = true;
        }
    }
        else
        {
            lastQuery = true;
    }
        if(!lastQuery)
        {
            rangeLow = rangeHigh + 1;
            rangeHigh = rangeLow + (rangeStep - 1);
    }
}
    while(!quitLoop);
}
catch(Exception ex)
{
    // Handle exception ex.
}

来源:http://systemmanager.ru/adam-sdk.en/netds/enumerating_members_in_a_large_group.htm