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 9 10527
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
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
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
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
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 > >
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 > > > > > >
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 > > > > > > > > > > >
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 > > > > > > > > > > > > > > > > > >
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. This discussion thread is closed Replies have been disabled for this discussion. Similar topics
10 posts
views
Thread by Randell D. |
last post: by
|
reply
views
Thread by kovac |
last post: by
|
5 posts
views
Thread by Brian Hanson |
last post: by
|
9 posts
views
Thread by Sameh Ahmed |
last post: by
| | | | | | | | | | | | | |