By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,550 Members | 1,733 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,550 IT Pros & Developers. It's quick & easy.

Security/Distribution Group Member.Count limit of 1000

P: n/a
Howdy,

I am having trouble with the objectCategory=group member.Count attribute.
I get one of three counts, a number between 1-999, no member (does not
contain member property), or 0. Using LDIFDE as a comparison I get the same
results. No members means just that, an empty group. Zero means that the
DirectorySearcher.SizeLimit has been exceeded.
http://msdn.microsoft.com/library/en...LimitTopic.asp
states:
....
Property Value
The maximum number of objects the server returns in a search. The default of
zero means to use the server-determined default size limit of 1000 entries.
Remarks
The server stops searching after the size limit is reached and returns the
results accumulated up to that point.
Note If you set SizeLimit to a value that is larger than the
server-determined default of 1000 entries, the server-determined default is
used.
....

My question is, what do I change on the server (domain controller) or
within Active Directory to increase the over-riding server-determined
default size limit of 1000? I tried the MS KB article (Controlling the
Active Directory Search Buffer Size
http://support.microsoft.com/?kbid=243281) Directory UI registry change to
noavail. We have alredy increased the NTDSUTIL's LDAP Policies to:
Policy Current(New)
MaxPoolThreads 8
MaxDatagramRecv 1024
MaxReceiveBuffer 10485760
InitRecvTimeout 120
MaxConnections 5000
MaxConnIdleTime 900
MaxActiveQueries 40
MaxPageSize 200000
MaxQueryDuration 120
MaxTempTableSize 10000
MaxResultSetSize 262144
MaxNotificationPerConn 5

--
Terry E Dow
Nov 15 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Hi,

You don't say what you are trying to do, or in what language, but in
VBScript you can use ADO and Range Limits to retrieve more than 1000 entries
in a multi-valued attribute, like the "member" attribute of a group object.
I have a sample VBScript program to enumerate group membership that uses
this technique linked on this page:

http://www.rlmueller.net/DocumentLargeGroup.htm

The technique is also described in Microsoft's "Windows 2000 Scripting
Guide", but the example is incomplete as it raises errors if there are fewer
than 1000 members left to retrieve.

As far as I know, there are not settings on the server to overcome this
limitation. I hope this helps.

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Howdy,

I am having trouble with the objectCategory=group member.Count attribute. I get one of three counts, a number between 1-999, no member (does not
contain member property), or 0. Using LDIFDE as a comparison I get the same results. No members means just that, an empty group. Zero means that the
DirectorySearcher.SizeLimit has been exceeded.
http://msdn.microsoft.com/library/en...LimitTopic.asp states:
...
Property Value
The maximum number of objects the server returns in a search. The default of zero means to use the server-determined default size limit of 1000 entries. Remarks
The server stops searching after the size limit is reached and returns the
results accumulated up to that point.
Note If you set SizeLimit to a value that is larger than the
server-determined default of 1000 entries, the server-determined default is used.
...

My question is, what do I change on the server (domain controller) or
within Active Directory to increase the over-riding server-determined
default size limit of 1000? I tried the MS KB article (Controlling the
Active Directory Search Buffer Size
http://support.microsoft.com/?kbid=243281) Directory UI registry change to
noavail. We have alredy increased the NTDSUTIL's LDAP Policies to:
Policy Current(New)
MaxPoolThreads 8
MaxDatagramRecv 1024
MaxReceiveBuffer 10485760
InitRecvTimeout 120
MaxConnections 5000
MaxConnIdleTime 900
MaxActiveQueries 40
MaxPageSize 200000
MaxQueryDuration 120
MaxTempTableSize 10000
MaxResultSetSize 262144
MaxNotificationPerConn 5

--
Terry E Dow

Nov 15 '05 #2

P: n/a
This is my generalized VB.NET range retrieval function. It returns the
attribute values in an ArrayList. You could easily modify it to use a
different container:

Protected Shared Function GetAllAttributeValues(ByVal entry As
DirectoryEntry, ByVal attributeName As String) As ArrayList
Dim propValues As PropertyValueCollection
Dim propValue As Object
Dim attributeValues As PropertyValueCollection
Dim values As ArrayList

Dim currentRange As String

Dim startCount As Integer
Dim endCount As Integer
Dim iteration As Integer

Dim increment As Integer = 1000
Dim expectedErrorCode As Integer = -2147016672

'This optimization reads the attributey directly if it
'contains less than 1000 values and returns an arraylist based
'on that. If we have 1000 values, we assume that there are
likely more than
'1000 values and we resort to the slower attribute ranging
method
'done below
entry.RefreshCache(New String() {attributeName})

attributeValues = entry.Properties(attributeName)
If attributeValues.Count < 1000 Then
Dim memberValue As Object
values = New ArrayList(attributeValues.Count)
For Each memberValue In attributeValues
values.Add(memberValue)
Next
values.TrimToSize()
Return values
End If

'here we go into ranging mode

values = New ArrayList(1000)

Do
startCount = iteration * increment
endCount = (iteration + 1) * increment - 1
'This is the attribute ranging method for retrieving the
contents of large attributes
currentRange = String.Format("{0};Range={1}-{2}",
attributeName, startCount, endCount)
'this will throw when the lower bound on the range is too
high
Try
entry.RefreshCache(New String() {currentRange})
Catch e As COMException 'I might check for the expected
hresult, but I don't know if I need to
Exit Do
End Try
'Get the values for for the current range of attributes
propValues = entry.Properties(attributeName)

For Each propValue In propValues
values.Add(propValue)
Next

iteration += 1
values.Capacity += increment

Loop

values.TrimToSize()
Return values
End Function

This should allow you to get full group membership in .NET (unless we are
talking about primary group membership which is done a different way).

Joe K.

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in
message news:ew*************@tk2msftngp13.phx.gbl...
Hi,

You don't say what you are trying to do, or in what language, but in
VBScript you can use ADO and Range Limits to retrieve more than 1000 entries in a multi-valued attribute, like the "member" attribute of a group object. I have a sample VBScript program to enumerate group membership that uses
this technique linked on this page:

http://www.rlmueller.net/DocumentLargeGroup.htm

The technique is also described in Microsoft's "Windows 2000 Scripting
Guide", but the example is incomplete as it raises errors if there are fewer than 1000 members left to retrieve.

As far as I know, there are not settings on the server to overcome this
limitation. I hope this helps.

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Howdy,

I am having trouble with the objectCategory=group member.Count attribute.
I get one of three counts, a number between 1-999, no member (does not
contain member property), or 0. Using LDIFDE as a comparison I get the

same
results. No members means just that, an empty group. Zero means that the DirectorySearcher.SizeLimit has been exceeded.

http://msdn.microsoft.com/library/en...LimitTopic.asp
states:
...
Property Value
The maximum number of objects the server returns in a search. The default of
zero means to use the server-determined default size limit of 1000

entries.
Remarks
The server stops searching after the size limit is reached and returns

the results accumulated up to that point.
Note If you set SizeLimit to a value that is larger than the
server-determined default of 1000 entries, the server-determined default

is
used.
...

My question is, what do I change on the server (domain controller) or
within Active Directory to increase the over-riding server-determined
default size limit of 1000? I tried the MS KB article (Controlling the
Active Directory Search Buffer Size
http://support.microsoft.com/?kbid=243281) Directory UI registry change to noavail. We have alredy increased the NTDSUTIL's LDAP Policies to:
Policy Current(New)
MaxPoolThreads 8
MaxDatagramRecv 1024
MaxReceiveBuffer 10485760
InitRecvTimeout 120
MaxConnections 5000
MaxConnIdleTime 900
MaxActiveQueries 40
MaxPageSize 200000
MaxQueryDuration 120
MaxTempTableSize 10000
MaxResultSetSize 262144
MaxNotificationPerConn 5

--
Terry E Dow


Nov 15 '05 #3

P: n/a
Richard,

Thanks for your quick response.

The purpose of this Active Directory administration tool was to build a
list of security/distribution groups within a domain, and return metrics
like the membership count. The administrators can use this report to clean
up their domain.

Thank you very much for your example code EnumGroup2.vbs. I can see that
you are using the RANGE flags in your LDAP query, and grabbing a 1000 at a
time. Unfortunately, unless you know otherwise, Visual Studio .Net 2003
System.DirectoryServices namespace does not natively support that particular
option. I'm writing this in C#, and everything was going so well, until I
ran into this limit. Odd that LDIFDE has the same limitation, and the
developers did not use your solution to get around it.

Perhaps I can mix your LDAP query syntax with C# via another provider than
ADSI or System.DirectoryServices.

--
Terry E Dow

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in
message news:ew*************@tk2msftngp13.phx.gbl...
Hi,

You don't say what you are trying to do, or in what language, but in
VBScript you can use ADO and Range Limits to retrieve more than 1000 entries in a multi-valued attribute, like the "member" attribute of a group object. I have a sample VBScript program to enumerate group membership that uses
this technique linked on this page:

http://www.rlmueller.net/DocumentLargeGroup.htm

The technique is also described in Microsoft's "Windows 2000 Scripting
Guide", but the example is incomplete as it raises errors if there are fewer than 1000 members left to retrieve.

As far as I know, there are not settings on the server to overcome this
limitation. I hope this helps.

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Howdy,

I am having trouble with the objectCategory=group member.Count attribute.
I get one of three counts, a number between 1-999, no member (does not
contain member property), or 0. Using LDIFDE as a comparison I get the

same
results. No members means just that, an empty group. Zero means that the DirectorySearcher.SizeLimit has been exceeded.

http://msdn.microsoft.com/library/en...LimitTopic.asp
states:
...
Property Value
The maximum number of objects the server returns in a search. The default of
zero means to use the server-determined default size limit of 1000

entries.
Remarks
The server stops searching after the size limit is reached and returns

the results accumulated up to that point.
Note If you set SizeLimit to a value that is larger than the
server-determined default of 1000 entries, the server-determined default

is
used.
...

My question is, what do I change on the server (domain controller) or
within Active Directory to increase the over-riding server-determined
default size limit of 1000? I tried the MS KB article (Controlling the
Active Directory Search Buffer Size
http://support.microsoft.com/?kbid=243281) Directory UI registry change to noavail. We have alredy increased the NTDSUTIL's LDAP Policies to:
Policy Current(New)
MaxPoolThreads 8
MaxDatagramRecv 1024
MaxReceiveBuffer 10485760
InitRecvTimeout 120
MaxConnections 5000
MaxConnIdleTime 900
MaxActiveQueries 40
MaxPageSize 200000
MaxQueryDuration 120
MaxTempTableSize 10000
MaxResultSetSize 262144
MaxNotificationPerConn 5

--
Terry E Dow



Nov 15 '05 #4

P: n/a
Does Joe Kaplan's solution for .NET, posted after mine, help?

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Richard,

Thanks for your quick response.

The purpose of this Active Directory administration tool was to build a
list of security/distribution groups within a domain, and return metrics
like the membership count. The administrators can use this report to clean up their domain.

Thank you very much for your example code EnumGroup2.vbs. I can see that you are using the RANGE flags in your LDAP query, and grabbing a 1000 at a
time. Unfortunately, unless you know otherwise, Visual Studio .Net 2003
System.DirectoryServices namespace does not natively support that particular option. I'm writing this in C#, and everything was going so well, until I
ran into this limit. Odd that LDIFDE has the same limitation, and the
developers did not use your solution to get around it.

Perhaps I can mix your LDAP query syntax with C# via another provider than ADSI or System.DirectoryServices.

--
Terry E Dow

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in
message news:ew*************@tk2msftngp13.phx.gbl...
Hi,

You don't say what you are trying to do, or in what language, but in
VBScript you can use ADO and Range Limits to retrieve more than 1000 entries
in a multi-valued attribute, like the "member" attribute of a group

object.
I have a sample VBScript program to enumerate group membership that uses
this technique linked on this page:

http://www.rlmueller.net/DocumentLargeGroup.htm

The technique is also described in Microsoft's "Windows 2000 Scripting
Guide", but the example is incomplete as it raises errors if there are

fewer
than 1000 members left to retrieve.

As far as I know, there are not settings on the server to overcome this
limitation. I hope this helps.

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Howdy,

I am having trouble with the objectCategory=group member.Count

attribute.
I get one of three counts, a number between 1-999, no member (does not
contain member property), or 0. Using LDIFDE as a comparison I get the
same
results. No members means just that, an empty group. Zero means that the DirectorySearcher.SizeLimit has been exceeded.

http://msdn.microsoft.com/library/en...LimitTopic.asp states:
...
Property Value
The maximum number of objects the server returns in a search. The default
of
zero means to use the server-determined default size limit of 1000

entries.
Remarks
The server stops searching after the size limit is reached and returns the results accumulated up to that point.
Note If you set SizeLimit to a value that is larger than the
server-determined default of 1000 entries, the server-determined default is
used.
...

My question is, what do I change on the server (domain controller)
or within Active Directory to increase the over-riding server-determined
default size limit of 1000? I tried the MS KB article (Controlling the Active Directory Search Buffer Size
http://support.microsoft.com/?kbid=243281) Directory UI registry

change to noavail. We have alredy increased the NTDSUTIL's LDAP Policies to:
Policy Current(New)
MaxPoolThreads 8
MaxDatagramRecv 1024
MaxReceiveBuffer 10485760
InitRecvTimeout 120
MaxConnections 5000
MaxConnIdleTime 900
MaxActiveQueries 40
MaxPageSize 200000
MaxQueryDuration 120
MaxTempTableSize 10000
MaxResultSetSize 262144
MaxNotificationPerConn 5

--
Terry E Dow


Nov 15 '05 #5

P: n/a
Richard and Joe,

Yes and no. Both of your examples show to use the range filter to grab
0-999 at a time. I now need to learn how to do this is my brain-dead simple
C# DirectoryServices application. While diagnosing the problem with your
clues shows me that there might be a way. If I dump the active variables
during one of these greater than 1000 member groups I get the following
information:

<debug.txt>

Note the ["member;range=0-999"]. I did not put this in. At the same
moment, the ["member"] property that I am accessing is responding with the
count of zero, though not an empty group. What I need to do is figure out
how to get to the ["member;range=0-999"] property, or assert my own
(["member;range=0-999"] ["member;range=1000-1999"]
["member;range=2000-2999"], etc) and follow in your example. But I do not
understand how that property was added, or the correct syntax to add the
range filter myself. I'll be more than happy to embarrass myself and post
my code, if that is acceptable in these groups.

We already have groups with more than 5000 members. They appear to be
working (perhaps they are not). The tool I am writing generates a report to
aid in identifying such large groups, so that we can deal with them, like
creating series of nested groups in their place. This is a general report
that can also bring to light other discrepancies (unintentional mix of
universal/global groups, mix of security/distribution groups, empty groups,
etc).

--
Terry E Dow

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in
message news:%2****************@TK2MSFTNGP11.phx.gbl...
Does Joe Kaplan's solution for .NET, posted after mine, help?

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Richard,

Thanks for your quick response.

The purpose of this Active Directory administration tool was to build a
list of security/distribution groups within a domain, and return metrics
like the membership count. The administrators can use this report to

clean
up their domain.

Thank you very much for your example code EnumGroup2.vbs. I can see

that
you are using the RANGE flags in your LDAP query, and grabbing a 1000 at a time. Unfortunately, unless you know otherwise, Visual Studio .Net 2003
System.DirectoryServices namespace does not natively support that

particular
option. I'm writing this in C#, and everything was going so well, until I ran into this limit. Odd that LDIFDE has the same limitation, and the
developers did not use your solution to get around it.

Perhaps I can mix your LDAP query syntax with C# via another provider

than
ADSI or System.DirectoryServices.

--
Terry E Dow

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in
message news:ew*************@tk2msftngp13.phx.gbl...
Hi,

You don't say what you are trying to do, or in what language, but in
VBScript you can use ADO and Range Limits to retrieve more than 1000

entries
in a multi-valued attribute, like the "member" attribute of a group

object.
I have a sample VBScript program to enumerate group membership that uses this technique linked on this page:

http://www.rlmueller.net/DocumentLargeGroup.htm

The technique is also described in Microsoft's "Windows 2000 Scripting
Guide", but the example is incomplete as it raises errors if there are

fewer
than 1000 members left to retrieve.

As far as I know, there are not settings on the server to overcome this limitation. I hope this helps.

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
> Howdy,
>
> I am having trouble with the objectCategory=group member.Count
attribute.
> I get one of three counts, a number between 1-999, no member (does not > contain member property), or 0. Using LDIFDE as a comparison I get the same
> results. No members means just that, an empty group. Zero means that the
> DirectorySearcher.SizeLimit has been exceeded.
>

http://msdn.microsoft.com/library/en...LimitTopic.asp > states:
> ...
> Property Value
> The maximum number of objects the server returns in a search. The

default
of
> zero means to use the server-determined default size limit of 1000
entries.
> Remarks
> The server stops searching after the size limit is reached and returns
the
> results accumulated up to that point.
> Note If you set SizeLimit to a value that is larger than the
> server-determined default of 1000 entries, the server-determined default is
> used.
> ...
>
> My question is, what do I change on the server (domain controller) or > within Active Directory to increase the over-riding
server-determined > default size limit of 1000? I tried the MS KB article (Controlling

the > Active Directory Search Buffer Size
> http://support.microsoft.com/?kbid=243281) Directory UI registry

change
to
> noavail. We have alredy increased the NTDSUTIL's LDAP Policies to:
> Policy Current(New)
> MaxPoolThreads 8
> MaxDatagramRecv 1024
> MaxReceiveBuffer 10485760
> InitRecvTimeout 120
> MaxConnections 5000
> MaxConnIdleTime 900
> MaxActiveQueries 40
> MaxPageSize 200000
> MaxQueryDuration 120
> MaxTempTableSize 10000
> MaxResultSetSize 262144
> MaxNotificationPerConn 5
>
> --
> Terry E Dow
>
>



Nov 15 '05 #6

P: n/a
Are you sure the function I posted won't work for you when converted to C#?
It works for me really well with all kinds of attributes including member.
It should be really easy to convert (any of the free converters out there
should do it for you). All you do is pass in the directoryentry object and
the name of the attribute you want to range over and it returns an arraylist
of values.

Note that my sample is clever in that is doesn't use the searcher to do the
ranging but uses another feature of ADSI which allows you to do this with a
normal IADs object. Normal ADSI users (non-.NET) can use this technique by
calling GetInfoEx with the range parameters instead of doing an ADO search.
I got this idea out of the SDK somewhere, so there should be a sample in old
VB or VBScript.

BTW, for groups with more than 5000 members, they might work and they might
not. They used to work fine in our environment for access checks and
whatnot (and we have some really really big ones!), but after about a year
they started causing replication failures that took down our DCs. Now we
have lots of apps that depend on these groups and are basically screwed as
many of them expect the membership to be flat and will break if we nest the
membership.

Unless you are moving to 2K3 AD real soon, I'd recommend avoiding groups
with with large membership.

Joe K.

"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:u6*************@TK2MSFTNGP11.phx.gbl...
Richard and Joe,

Yes and no. Both of your examples show to use the range filter to grab
0-999 at a time. I now need to learn how to do this is my brain-dead simple C# DirectoryServices application. While diagnosing the problem with your
clues shows me that there might be a way. If I dump the active variables
during one of these greater than 1000 member groups I get the following
information:

<debug.txt>

Note the ["member;range=0-999"]. I did not put this in. At the same
moment, the ["member"] property that I am accessing is responding with the
count of zero, though not an empty group. What I need to do is figure out
how to get to the ["member;range=0-999"] property, or assert my own
(["member;range=0-999"] ["member;range=1000-1999"]
["member;range=2000-2999"], etc) and follow in your example. But I do not
understand how that property was added, or the correct syntax to add the
range filter myself. I'll be more than happy to embarrass myself and post
my code, if that is acceptable in these groups.

We already have groups with more than 5000 members. They appear to be
working (perhaps they are not). The tool I am writing generates a report to aid in identifying such large groups, so that we can deal with them, like
creating series of nested groups in their place. This is a general report
that can also bring to light other discrepancies (unintentional mix of
universal/global groups, mix of security/distribution groups, empty groups, etc).

--
Terry E Dow

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in
message news:%2****************@TK2MSFTNGP11.phx.gbl...
Does Joe Kaplan's solution for .NET, posted after mine, help?

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Richard,

Thanks for your quick response.

The purpose of this Active Directory administration tool was to build
a
list of security/distribution groups within a domain, and return
metrics like the membership count. The administrators can use this report to clean
up their domain.

Thank you very much for your example code EnumGroup2.vbs. I can see

that
you are using the RANGE flags in your LDAP query, and grabbing a 1000 at a time. Unfortunately, unless you know otherwise, Visual Studio .Net
2003 System.DirectoryServices namespace does not natively support that particular
option. I'm writing this in C#, and everything was going so well, until I ran into this limit. Odd that LDIFDE has the same limitation, and the
developers did not use your solution to get around it.

Perhaps I can mix your LDAP query syntax with C# via another
provider
than
ADSI or System.DirectoryServices.

--
Terry E Dow

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote
in message news:ew*************@tk2msftngp13.phx.gbl...
> Hi,
>
> You don't say what you are trying to do, or in what language, but in
> VBScript you can use ADO and Range Limits to retrieve more than 1000
entries
> in a multi-valued attribute, like the "member" attribute of a group
object.
> I have a sample VBScript program to enumerate group membership that

uses > this technique linked on this page:
>
> http://www.rlmueller.net/DocumentLargeGroup.htm
>
> The technique is also described in Microsoft's "Windows 2000 Scripting > Guide", but the example is incomplete as it raises errors if there are fewer
> than 1000 members left to retrieve.
>
> As far as I know, there are not settings on the server to overcome this > limitation. I hope this helps.
>
> --
> Richard
> Microsoft MVP Scripting and ADSI
> HilltopLab web site - http://www.rlmueller.net
> --
> "Terry E Dow" <Te******@verizon.neXt> wrote in message
> news:%2****************@TK2MSFTNGP12.phx.gbl...
> > Howdy,
> >
> > I am having trouble with the objectCategory=group member.Count
> attribute.
> > I get one of three counts, a number between 1-999, no member (does not > > contain member property), or 0. Using LDIFDE as a comparison I get the
> same
> > results. No members means just that, an empty group. Zero means that the
> > DirectorySearcher.SizeLimit has been exceeded.
> >
>

http://msdn.microsoft.com/library/en...LimitTopic.asp > > states:
> > ...
> > Property Value
> > The maximum number of objects the server returns in a search. The
default
> of
> > zero means to use the server-determined default size limit of 1000
> entries.
> > Remarks
> > The server stops searching after the size limit is reached and returns the
> > results accumulated up to that point.
> > Note If you set SizeLimit to a value that is larger than the
> > server-determined default of 1000 entries, the server-determined

default
> is
> > used.
> > ...
> >
> > My question is, what do I change on the server (domain controller)
or
> > within Active Directory to increase the over-riding server-determined > > default size limit of 1000? I tried the MS KB article
(Controlling the
> > Active Directory Search Buffer Size
> > http://support.microsoft.com/?kbid=243281) Directory UI registry

change
to
> > noavail. We have alredy increased the NTDSUTIL's LDAP Policies

to: > > Policy Current(New)
> > MaxPoolThreads 8
> > MaxDatagramRecv 1024
> > MaxReceiveBuffer 10485760
> > InitRecvTimeout 120
> > MaxConnections 5000
> > MaxConnIdleTime 900
> > MaxActiveQueries 40
> > MaxPageSize 200000
> > MaxQueryDuration 120
> > MaxTempTableSize 10000
> > MaxResultSetSize 262144
> > MaxNotificationPerConn 5
> >
> > --
> > Terry E Dow
> >
> >
>
>


Nov 15 '05 #7

P: n/a
Joe and Richard,

Many thanks for your support and examples. I did get it to work. At
first the VB to C# conversion seemed daunting, but I did a little step by
step, and made it to the other side.

<typical DirectorySearcher and SearchResults stuff>
....
// Write member.Count
if (myResult.Properties.Contains("member"))
{
if (myResult.Properties["member"].Count != 0)
{
Console.Write( ",{0}", myResult.Properties["member"].Count.ToString() );
}
else
{
// Result of 0 means count exceeds server defined limit of 1000 (?!)
// Must request a block of 1000 items at a time.

int rangeIncrement = 1000; // Server defined default limit.
int rangeStart = 0;
int rangeEnd = rangeIncrement - 1;
string[] memberRange = { "" };

// Bind directly to group.
DirectoryEntry myGroup = myResult.GetDirectoryEntry();

// Grab a rangeIncrement at a time.
int memberCount = 0;
do
{

// Build propertyNames with range filter.
memberRange[0] = string.Format( "member;Range={0}-{1}", rangeStart,
rangeEnd );

// I haven't a clue why this works...but it does.
myGroup.RefreshCache( memberRange );

// Collect data.
memberCount += myGroup.Properties["member"].Count;

// Increment request range.
rangeStart += rangeIncrement;
rangeEnd += rangeIncrement;

} while ( myGroup.Properties["member"].Count == rangeIncrement );

Console.Write( ",{0}", memberCount );
}
}
else
{
// Result of 'not contains' means no members (zero count).
Console.Write( ",0" );
}
....

I was able to dispense with the try/catch with a exit loop condition. I
suspected group memberships that are an even multiple of rangeIncrement
would trigger an error. So I created a group with 999, 1000, and 1001
members and it ran without errors or try/catch. I did not test with 1999,
2000, 2001 members though.

Thanks again.

--
Terry E Dow
"Joe Kaplan (MVP - ADSI)" <jo*************@removethis.accenture.com> wrote
in message news:%2***************@TK2MSFTNGP11.phx.gbl...
Are you sure the function I posted won't work for you when converted to C#? It works for me really well with all kinds of attributes including member.
It should be really easy to convert (any of the free converters out there
should do it for you). All you do is pass in the directoryentry object and the name of the attribute you want to range over and it returns an arraylist of values.

Note that my sample is clever in that is doesn't use the searcher to do the ranging but uses another feature of ADSI which allows you to do this with a normal IADs object. Normal ADSI users (non-.NET) can use this technique by calling GetInfoEx with the range parameters instead of doing an ADO search. I got this idea out of the SDK somewhere, so there should be a sample in old VB or VBScript.

BTW, for groups with more than 5000 members, they might work and they might not. They used to work fine in our environment for access checks and
whatnot (and we have some really really big ones!), but after about a year
they started causing replication failures that took down our DCs. Now we
have lots of apps that depend on these groups and are basically screwed as
many of them expect the membership to be flat and will break if we nest the membership.

Unless you are moving to 2K3 AD real soon, I'd recommend avoiding groups
with with large membership.

Joe K.

"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:u6*************@TK2MSFTNGP11.phx.gbl...
Richard and Joe,

Yes and no. Both of your examples show to use the range filter to grab
0-999 at a time. I now need to learn how to do this is my brain-dead simple
C# DirectoryServices application. While diagnosing the problem with your clues shows me that there might be a way. If I dump the active variables during one of these greater than 1000 member groups I get the following
information:

<debug.txt>

Note the ["member;range=0-999"]. I did not put this in. At the same
moment, the ["member"] property that I am accessing is responding with the count of zero, though not an empty group. What I need to do is figure out how to get to the ["member;range=0-999"] property, or assert my own
(["member;range=0-999"] ["member;range=1000-1999"]
["member;range=2000-2999"], etc) and follow in your example. But I do not understand how that property was added, or the correct syntax to add the
range filter myself. I'll be more than happy to embarrass myself and post my code, if that is acceptable in these groups.

We already have groups with more than 5000 members. They appear to be
working (perhaps they are not). The tool I am writing generates a report to
aid in identifying such large groups, so that we can deal with them,
like creating series of nested groups in their place. This is a general report that can also bring to light other discrepancies (unintentional mix of
universal/global groups, mix of security/distribution groups, empty

groups,
etc).

--
Terry E Dow

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in
message news:%2****************@TK2MSFTNGP11.phx.gbl...
Does Joe Kaplan's solution for .NET, posted after mine, help?

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
> Richard,
>
> Thanks for your quick response.
>
> The purpose of this Active Directory administration tool was to build
a
> list of security/distribution groups within a domain, and return

metrics > like the membership count. The administrators can use this report to clean
> up their domain.
>
> Thank you very much for your example code EnumGroup2.vbs. I can see that
> you are using the RANGE flags in your LDAP query, and grabbing a 1000 at
a
> time. Unfortunately, unless you know otherwise, Visual Studio .Net 2003 > System.DirectoryServices namespace does not natively support that
particular
> option. I'm writing this in C#, and everything was going so well, until
I
> ran into this limit. Odd that LDIFDE has the same limitation, and
the > developers did not use your solution to get around it.
>
> Perhaps I can mix your LDAP query syntax with C# via another

provider than
> ADSI or System.DirectoryServices.
>
> --
> Terry E Dow
>
> "Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in
> message news:ew*************@tk2msftngp13.phx.gbl...
> > Hi,
> >
> > You don't say what you are trying to do, or in what language, but
in > > VBScript you can use ADO and Range Limits to retrieve more than 1000 > entries
> > in a multi-valued attribute, like the "member" attribute of a group > object.
> > I have a sample VBScript program to enumerate group membership that uses
> > this technique linked on this page:
> >
> > http://www.rlmueller.net/DocumentLargeGroup.htm
> >
> > The technique is also described in Microsoft's "Windows 2000 Scripting > > Guide", but the example is incomplete as it raises errors if there are > fewer
> > than 1000 members left to retrieve.
> >
> > As far as I know, there are not settings on the server to overcome

this
> > limitation. I hope this helps.
> >
> > --
> > Richard
> > Microsoft MVP Scripting and ADSI
> > HilltopLab web site - http://www.rlmueller.net
> > --
> > "Terry E Dow" <Te******@verizon.neXt> wrote in message
> > news:%2****************@TK2MSFTNGP12.phx.gbl...
> > > Howdy,
> > >
> > > I am having trouble with the objectCategory=group member.Count
> > attribute.
> > > I get one of three counts, a number between 1-999, no member
(does not
> > > contain member property), or 0. Using LDIFDE as a comparison I get the
> > same
> > > results. No members means just that, an empty group. Zero
means that
> the
> > > DirectorySearcher.SizeLimit has been exceeded.
> > >
> >
>

http://msdn.microsoft.com/library/en...LimitTopic.asp > > > states:
> > > ...
> > > Property Value
> > > The maximum number of objects the server returns in a search. The > default
> > of
> > > zero means to use the server-determined default size limit of 1000 > > entries.
> > > Remarks
> > > The server stops searching after the size limit is reached and

returns
> the
> > > results accumulated up to that point.
> > > Note If you set SizeLimit to a value that is larger than the
> > > server-determined default of 1000 entries, the server-determined
default
> > is
> > > used.
> > > ...
> > >
> > > My question is, what do I change on the server (domain

controller) or
> > > within Active Directory to increase the over-riding

server-determined
> > > default size limit of 1000? I tried the MS KB article (Controlling the
> > > Active Directory Search Buffer Size
> > > http://support.microsoft.com/?kbid=243281) Directory UI registry
change
> to
> > > noavail. We have alredy increased the NTDSUTIL's LDAP Policies to: > > > Policy Current(New)
> > > MaxPoolThreads 8
> > > MaxDatagramRecv 1024
> > > MaxReceiveBuffer 10485760
> > > InitRecvTimeout 120
> > > MaxConnections 5000
> > > MaxConnIdleTime 900
> > > MaxActiveQueries 40
> > > MaxPageSize 200000
> > > MaxQueryDuration 120
> > > MaxTempTableSize 10000
> > > MaxResultSetSize 262144
> > > MaxNotificationPerConn 5
> > >
> > > --
> > > Terry E Dow
> > >
> > >
> >
> >
>



Nov 15 '05 #8

P: n/a
Hi Terry,

The entry.RefreshCache technique works because range retrieval works with
IADs::GetInfoEx and RefreshCache wraps that function. I think it is the
easiest and fastest technique. It is documented here:

http://msdn.microsoft.com/library/de...asp?frame=true

You can also do it in .NET with the DirectorySearcher class, but I think
that approach is more slower and more difficult. I had a function that used
that technique previously, but I've since abandoned it.

Glad you got it working. I should fix my function if it is throwing an
exception for no reason. No sense in taking that perf hit.

Cheers,

Joe K.

"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:uM**************@TK2MSFTNGP11.phx.gbl...
Joe and Richard,

Many thanks for your support and examples. I did get it to work. At
first the VB to C# conversion seemed daunting, but I did a little step by
step, and made it to the other side.

<typical DirectorySearcher and SearchResults stuff>
...
// Write member.Count
if (myResult.Properties.Contains("member"))
{
if (myResult.Properties["member"].Count != 0)
{
Console.Write( ",{0}", myResult.Properties["member"].Count.ToString() );
}
else
{
// Result of 0 means count exceeds server defined limit of 1000 (?!)
// Must request a block of 1000 items at a time.

int rangeIncrement = 1000; // Server defined default limit.
int rangeStart = 0;
int rangeEnd = rangeIncrement - 1;
string[] memberRange = { "" };

// Bind directly to group.
DirectoryEntry myGroup = myResult.GetDirectoryEntry();

// Grab a rangeIncrement at a time.
int memberCount = 0;
do
{

// Build propertyNames with range filter.
memberRange[0] = string.Format( "member;Range={0}-{1}", rangeStart,
rangeEnd );

// I haven't a clue why this works...but it does.
myGroup.RefreshCache( memberRange );

// Collect data.
memberCount += myGroup.Properties["member"].Count;

// Increment request range.
rangeStart += rangeIncrement;
rangeEnd += rangeIncrement;

} while ( myGroup.Properties["member"].Count == rangeIncrement );

Console.Write( ",{0}", memberCount );
}
}
else
{
// Result of 'not contains' means no members (zero count).
Console.Write( ",0" );
}
...

I was able to dispense with the try/catch with a exit loop condition. I
suspected group memberships that are an even multiple of rangeIncrement
would trigger an error. So I created a group with 999, 1000, and 1001
members and it ran without errors or try/catch. I did not test with 1999,
2000, 2001 members though.

Thanks again.

--
Terry E Dow
"Joe Kaplan (MVP - ADSI)" <jo*************@removethis.accenture.com> wrote
in message news:%2***************@TK2MSFTNGP11.phx.gbl...
Are you sure the function I posted won't work for you when converted to C#?
It works for me really well with all kinds of attributes including member.
It should be really easy to convert (any of the free converters out there should do it for you). All you do is pass in the directoryentry object

and
the name of the attribute you want to range over and it returns an

arraylist
of values.

Note that my sample is clever in that is doesn't use the searcher to do

the
ranging but uses another feature of ADSI which allows you to do this with a
normal IADs object. Normal ADSI users (non-.NET) can use this technique by
calling GetInfoEx with the range parameters instead of doing an ADO

search.
I got this idea out of the SDK somewhere, so there should be a sample in

old
VB or VBScript.

BTW, for groups with more than 5000 members, they might work and they

might
not. They used to work fine in our environment for access checks and
whatnot (and we have some really really big ones!), but after about a

year they started causing replication failures that took down our DCs. Now we have lots of apps that depend on these groups and are basically screwed as many of them expect the membership to be flat and will break if we nest

the
membership.

Unless you are moving to 2K3 AD real soon, I'd recommend avoiding groups
with with large membership.

Joe K.

"Terry E Dow" <Te******@verizon.neXt> wrote in message
news:u6*************@TK2MSFTNGP11.phx.gbl...
Richard and Joe,

Yes and no. Both of your examples show to use the range filter to grab 0-999 at a time. I now need to learn how to do this is my brain-dead

simple
C# DirectoryServices application. While diagnosing the problem with your clues shows me that there might be a way. If I dump the active variables during one of these greater than 1000 member groups I get the following information:

<debug.txt>

Note the ["member;range=0-999"]. I did not put this in. At the same moment, the ["member"] property that I am accessing is responding with the count of zero, though not an empty group. What I need to do is figure out how to get to the ["member;range=0-999"] property, or assert my own
(["member;range=0-999"] ["member;range=1000-1999"]
["member;range=2000-2999"], etc) and follow in your example. But I do not understand how that property was added, or the correct syntax to add the range filter myself. I'll be more than happy to embarrass myself and post my code, if that is acceptable in these groups.

We already have groups with more than 5000 members. They appear to be working (perhaps they are not). The tool I am writing generates a report
to
aid in identifying such large groups, so that we can deal with them,

like creating series of nested groups in their place. This is a general report that can also bring to light other discrepancies (unintentional mix of
universal/global groups, mix of security/distribution groups, empty

groups,
etc).

--
Terry E Dow

"Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote in message news:%2****************@TK2MSFTNGP11.phx.gbl...
> Does Joe Kaplan's solution for .NET, posted after mine, help?
>
> --
> Richard
> Microsoft MVP Scripting and ADSI
> HilltopLab web site - http://www.rlmueller.net
> --
> "Terry E Dow" <Te******@verizon.neXt> wrote in message
> news:%2****************@TK2MSFTNGP10.phx.gbl...
> > Richard,
> >
> > Thanks for your quick response.
> >
> > The purpose of this Active Directory administration tool was to

build
a
> > list of security/distribution groups within a domain, and return

metrics
> > like the membership count. The administrators can use this report to > clean
> > up their domain.
> >
> > Thank you very much for your example code EnumGroup2.vbs. I can see > that
> > you are using the RANGE flags in your LDAP query, and grabbing a 1000
at
a
> > time. Unfortunately, unless you know otherwise, Visual Studio ..Net 2003
> > System.DirectoryServices namespace does not natively support that
> particular
> > option. I'm writing this in C#, and everything was going so well,

until
I
> > ran into this limit. Odd that LDIFDE has the same limitation, and the > > developers did not use your solution to get around it.
> >
> > Perhaps I can mix your LDAP query syntax with C# via another

provider
> than
> > ADSI or System.DirectoryServices.
> >
> > --
> > Terry E Dow
> >
> > "Richard Mueller [MVP]" <rl**************@ameritech.NOSPAM.net> wrote
in
> > message news:ew*************@tk2msftngp13.phx.gbl...
> > > Hi,
> > >
> > > You don't say what you are trying to do, or in what language,

but in > > > VBScript you can use ADO and Range Limits to retrieve more than 1000 > > entries
> > > in a multi-valued attribute, like the "member" attribute of a group > > object.
> > > I have a sample VBScript program to enumerate group membership that uses
> > > this technique linked on this page:
> > >
> > > http://www.rlmueller.net/DocumentLargeGroup.htm
> > >
> > > The technique is also described in Microsoft's "Windows 2000

Scripting
> > > Guide", but the example is incomplete as it raises errors if
there are
> > fewer
> > > than 1000 members left to retrieve.
> > >
> > > As far as I know, there are not settings on the server to
overcome this
> > > limitation. I hope this helps.
> > >
> > > --
> > > Richard
> > > Microsoft MVP Scripting and ADSI
> > > HilltopLab web site - http://www.rlmueller.net
> > > --
> > > "Terry E Dow" <Te******@verizon.neXt> wrote in message
> > > news:%2****************@TK2MSFTNGP12.phx.gbl...
> > > > Howdy,
> > > >
> > > > I am having trouble with the objectCategory=group member.Count > > > attribute.
> > > > I get one of three counts, a number between 1-999, no member

(does not
> > > > contain member property), or 0. Using LDIFDE as a comparison I get
> the
> > > same
> > > > results. No members means just that, an empty group. Zero means that
> > the
> > > > DirectorySearcher.SizeLimit has been exceeded.
> > > >
> > >
> >
>

http://msdn.microsoft.com/library/en...LimitTopic.asp > > > > states:
> > > > ...
> > > > Property Value
> > > > The maximum number of objects the server returns in a search. The > > default
> > > of
> > > > zero means to use the server-determined default size limit of 1000 > > > entries.
> > > > Remarks
> > > > The server stops searching after the size limit is reached and
returns
> > the
> > > > results accumulated up to that point.
> > > > Note If you set SizeLimit to a value that is larger than the
> > > > server-determined default of 1000 entries, the server-determined > default
> > > is
> > > > used.
> > > > ...
> > > >
> > > > My question is, what do I change on the server (domain

controller)
> or
> > > > within Active Directory to increase the over-riding
server-determined
> > > > default size limit of 1000? I tried the MS KB article

(Controlling
> the
> > > > Active Directory Search Buffer Size
> > > > http://support.microsoft.com/?kbid=243281) Directory UI registry > change
> > to
> > > > noavail. We have alredy increased the NTDSUTIL's LDAP
Policies to:
> > > > Policy Current(New)
> > > > MaxPoolThreads 8
> > > > MaxDatagramRecv 1024
> > > > MaxReceiveBuffer 10485760
> > > > InitRecvTimeout 120
> > > > MaxConnections 5000
> > > > MaxConnIdleTime 900
> > > > MaxActiveQueries 40
> > > > MaxPageSize 200000
> > > > MaxQueryDuration 120
> > > > MaxTempTableSize 10000
> > > > MaxResultSetSize 262144
> > > > MaxNotificationPerConn 5
> > > >
> > > > --
> > > > Terry E Dow
> > > >
> > > >
> > >
> > >
> >
>
>


Nov 15 '05 #9

P: n/a
Hi,
I didn't read whole thread, but how about using DirectorySearcher for paged
search, SearchScope.base and member as the only property to load. That
should return you as many members as there are (no 1000 limitaiton).

-Valery.
Nov 15 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.