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;subtree,$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
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] Sent: Wednesday, March 16, 2011 11:09 PM To: Steven Manross; 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
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] Sent: Wednesday, March 16, 2011 11:09 PM To: Steven Manross; 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
RE: LDAP query limit in AD?
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.commailto: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.commailto:perl95...@yahoo.com] Sent: Wednesday, March 16, 2011 11:09 PM To: Steven Manross; perl-win32-admin@listserv.ActiveState.commailto: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