A F -

I'm certain I used code or doco [or a book?] that was authored by Steven 
Manross.  I ran into the same issue when I promoted a solution from a 
development environment to production.  Development had < 1000 objects of 
interest, production exceeded the limit of 1000 per query.  I ended up using 
the paged method that Steven mentioned in his post.

My apologies for top-posting.

Here's a sequence of calls that I used to query AD for printQueue objects.  In 
our environment there's more than 1000.

use constant LDAP_SIZELIMIT => 0;
use constant LDAP_SCOPE => 'sub';
use constant LDAP_FILTER => '(objectCategory=printQueue)';
use constant LDAP_ATTR => 'portName';
use constant PAGE_SIZE => 500;

#
# sub makeBaseDN takes a DNS-style domain and turned it into the X.400 [or is 
it X.500] style format.
#

  my( $ldapHost, $ID, $PW ) = @_;
  my( $ldap ) = Net::LDAP->new( $ldapHost ) or die "$@";
  my( $mesg, $page, $cookie, $objCount ) = ( undef, undef, undef, 0 );
  my( @args ) = ();

  if ( length( $ID ) == 0 || length( $PW ) == 0 ) {
    printf $tee "%s: an ID and password must be specified to bind to the LDAP se
    exit -1;
  }

  # bind to a directory with dn and password
  # NOTE: bind() method fails if the connection cannot be completed because of n
  #       failure is "Can't call method "bind" on an undefined value at getPrint
  $mesg = $ldap->bind( $ID, password => $PW );

  # NOTE: failure occurs here when $ID and/or $PW is incorrect, failure is:
  #       80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error
  $mesg->code && die $mesg->error;
  $page = Net::LDAP::Control::Paged->new( size => PAGE_SIZE );

  @args = (
            Sizelimit => LDAP_SIZELIMIT,
            scope     => LDAP_SCOPE,
            base      => &makeBaseDN,
            filter    => LDAP_FILTER,
            attrs     => [ LDAP_ATTR ],
            control   => [ $page ],
  );

  while( 1 ) {
    $mesg = $ldap->search( @args );

    last if ( $mesg->code && $mesg->code != 4 );

   foreach my $entry ( $mesg->entries ) {
      my $dn = $entry->dn();
      foreach my $attr ( $entry->attributes ) {
        my $value = $entry->get_value( $attr );
        $value =~ s/^IP_//;
        printf QUE "%s\t%s\n", $value, $dn;
        printf IP "%s\n", $value;
      }
    }
    $objCount += $mesg->count;

    last unless my( $resp ) = $mesg->control( LDAP_CONTROL_PAGED );
    last unless $cookie = $resp->cookie;
    $page->cookie( $cookie );
  }

  if ( $cookie ) {
    printf $tee "INFO: query interrupted: %s: %s!\n", $mesg->code, $mesg->error;
    $page->cookie( $cookie );
    $page->size( 0 );
    $ldap->search( @args );

    if ( $mesg->count && $objCount == 0 ) {

    foreach my $entry ( $mesg->entries ) {
      my $dn = $entry->dn();
      foreach my $attr ( $entry->attributes ) {
        my $value = $entry->get_value( $attr );
        $value =~ s/^IP_//;
        printf QUE "%s\t%s\n", $value, $dn;
        printf IP "%s\n", $value;
      }
    }
    $objCount += $mesg->count;
  }

  if ( $objCount ) {
    # query actually returned something
  }

  $mesg = $ldap->unbind;  # take down session



--
Paul J. Brzezinski
Integration Engineering - GM
HP Enterprise Services
Telephone +1 248.365.9615
Email paul.brzezin...@hp.com<mailto:paul.brzezin...@hp.com>

From: perl-win32-admin-boun...@listserv.activestate.com 
[mailto:perl-win32-admin-boun...@listserv.activestate.com] On Behalf Of A F
Sent: Thursday, March 17, 2011 2:54 PM
To: Steven Manross; perl-win32-admin@listserv.ActiveState.com
Subject: Re: LDAP query limit in AD?

Even with that it only give me 1000. the recordcount seems to be always 1000 
with any kind of filter I put.
In my previous example I was expecting 1600+ users that have manager.




________________________________
From: Steven Manross <ste...@manross.net>
To: A F <perl95...@yahoo.com>; perl-win32-admin@listserv.ActiveState.com
Sent: Wed, March 16, 2011 11:34:17 PM
Subject: RE: LDAP query limit in AD?

Your code should pull all the users with a specified manager.

While there is a limit of 1000 objects that AD will pull back in an AD
query, we've written a paged query (  $Cmd->{Properties}->{"Page Size"}
= 99), to get around that limitation so I would start by modifying your
query to change:

(&(objectclass=User)(manager=*))

To:

(objectclass=User)

And note the differences of results..  I am guessing that will show your
missing 1000+ users.

HTH
Steven
________________________________

    From: A F [mailto:perl95...@yahoo.com<mailto:perl95...@yahoo.com>]
    Sent: Wednesday, March 16, 2011 11:09 PM
    To: Steven Manross; 
perl-win32-admin@listserv.ActiveState.com<mailto:perl-win32-admin@listserv.ActiveState.com>
    Subject: LDAP query limit in AD?


    Is there a limit on the number of record when doing a AD query
with LDAP?
    I am getting only 1000 records from this script. We have more
than 2000+ users in our AD.
    Any idea how to increase the limit to get everything?


    use Win32::OLE;
    my $RootDSE = Win32::OLE->GetObject("LDAP://RootDSE");


    $dc = $RootDSE->Get("DnsHostName");
    print "$dc\n";
    query_ldap("<LDAP://" . $dc .
">;(&(objectclass=User)(manager=*));displayname,distinguishedname;subtre
e",$objects);

    print "recordcount = ".$objects->{RecordCount}."\n";
    while (!$objects->{EOF}) {

getattributes($dc,$objects->Fields("distinguishedname")->{Value});
      $objects->MoveNext();
    }
    sub query_ldap {
      my $ldap_query = $_[0];
      my $error_num;
      my $error_name;
      my $RS;
      my $Conn = Win32::OLE->new("ADODB.Connection");
      if (Win32::OLE->LastError() != 0) {
        print "Failed creating ADODB.Connection object
(".Win32::OLE->LastError().")\n  -> $ldap_query\n";
        return 0;
      }
      $Conn->{'Provider'} = "ADsDSOObject";
      if (Win32::OLE->LastError() != 0) {
        print "Failed setting ADODB.Command Provider
(".Win32::OLE->LastError().")\n  -> $ldap_query\n";
        return 0;
      }
      $Conn->{Open} = "Perl Active Directory Query";
      my $Cmd = Win32::OLE->new("ADODB.Command");
      if (Win32::OLE->LastError() != 0) {
        print "Failed creating ADODB.Command object
(".Win32::OLE->LastError().")\n  -> $ldap_query\n";
        return 0;
      }
      $Cmd->{CommandText} = $ldap_query;
      $Cmd->{Properties}->{"Page Size"} = 99;
      $Cmd->{ActiveConnection} = $Conn;
      $RS = $Cmd->Execute();
      if (Win32::OLE->LastError() != 0) {
        print "Failed Executing ADODB Command object
(".Win32::OLE->LastError().")\nExecuting ADODB Command ->
$ldap_query\n";
        return 0;
      } else {
        $_[1] = $RS;
        return 1;
      }
    }
    sub getattributes  {
      my $dc = $_[0];
      my $dn = $_[1];
      my $adsuser = Win32::OLE->GetObject("LDAP://$dc/$dn") || die
("Can't find user: ".Win32::OLE->LastError()."\n");
      print "$adsuser->{cn}\t";
      print "$adsuser->{EmailAddress}\t";
      print "$adsuser->{department}\t";
      print "$adsuser->{PhysicalDeliveryOfficeName}\t";
      print "  Manager: $adsuser->{Manager}\n";
    }





_______________________________________________
Perl-Win32-Admin mailing list
Perl-Win32-Admin@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to