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 [email protected]<mailto:[email protected]>
From: [email protected]
[mailto:[email protected]] On Behalf Of A F
Sent: Thursday, March 17, 2011 2:54 PM
To: Steven Manross; [email protected]
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 <[email protected]>
To: A F <[email protected]>; [email protected]
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:[email protected]<mailto:[email protected]>]
Sent: Wednesday, March 16, 2011 11:09 PM
To: Steven Manross;
[email protected]<mailto:[email protected]>
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
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs