|
server
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
How to tally group membership for huge group +10k accounts?
Need a count of users/computers in a group membership that is upwards
of 13-15k accounts. ADSI is no go and stops at 1500 ADO putters out at 6110 csvde dies at 1500 as well ldifde gets a bit more, at least 10k, but the format is terrible. Don't really need a long list would be happy with just a echo of the number of accounts in group. Sport wrote:
> Need a count of users/computers in a group membership that is upwards To document groups with more than 1500 members you have to use ADO range > of 13-15k accounts. > > ADSI is no go and stops at 1500 > ADO putters out at 6110 > csvde dies at 1500 as well > ldifde gets a bit more, at least 10k, but the format is terrible. > > Don't really need a long list would be happy with just a echo of the > number of accounts in group. > limits to retrieve all values of the member attribute of the group. I have a sample VBScript that uses this technique to document large groups linked here: http://www.rlmueller.net/DocumentLargeGroup.htm However, you can also query for all objects that have the group DN in the memberOf attribute. Instead of one row with thousands of values, you get a recordset with thousands of rows. You just need to use paging if you enumerate the recordset, but if all you need is the count you can use the RecordCount property. In brief: =========== ' Specify Distinguished Name of the large group. strGroupDN = "cn=Big Group,ou=Sales,dc=MyDomain,dc=com" ' Use ADO to search the domain for members of the group. Set adoConnection = CreateObject("ADODB.Connection") Set adoCommand = CreateObject("ADODB.Command") adoConnection.Provider = "ADsDSOOBject" adoConnection.Open "Active Directory Provider" Set adoCommand.ActiveConnection = adoConnection ' Determine the DNS domain from the RootDSE object. Set objRootDSE = GetObject("LDAP://RootDSE") strDNSDomain = objRootDSE.Get("defaultNamingContext") ' Filter on all objects that are members of the group. strFilter = "(memberOf=" & strGroupDN & ")" ' Construct the LDAP syntax query. strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter _ & ";distinguishedName;subtree" ' Run the query. adoCommand.CommandText = strQuery adoCommand.Properties("Page Size") = 100 adoCommand.Properties("Timeout") = 30 adoCommand.Properties("Cache Results") = False Set adoRecordset = adoCommand.Execute ' Retrieve number of records. strNumber = adoRecordset.RecordCount Wscript.Echo "Number of members: " & strNumber ' Clean up. adoRecordset.Close adoConnection.Close ============ Or, you could enumerate the recordset with: ' Enumerate all members. Set adoRecordset = adoCommand.Execute Do Until adoRecordset.EOF strDN = adoRecordset.Fields("distinguishedName").Value Wscript.Echo strDN adoRecordset.MoveNext Loop But if you do both (enumerate and retrieve the count), you must use: adoRecordset.CursorType = 3 and after retrieving the count use: adoRecordset.MoveFirst before the loop to enumerate the recordset. However, I suspect you just want the count. Thanks Richard!
The first thing I did was run your ADO Large Group and it stops at 6110 for whatever reason. ldifde works but is not great looking. Will try below, thanks again. Richard Mueller [MVP] wrote: Show quote > Sport wrote: > > > Need a count of users/computers in a group membership that is upwards > > of 13-15k accounts. > > > > ADSI is no go and stops at 1500 > > ADO putters out at 6110 > > csvde dies at 1500 as well > > ldifde gets a bit more, at least 10k, but the format is terrible. > > > > Don't really need a long list would be happy with just a echo of the > > number of accounts in group. > > > > To document groups with more than 1500 members you have to use ADO range > limits to retrieve all values of the member attribute of the group. I have a > sample VBScript that uses this technique to document large groups linked > here: > > http://www.rlmueller.net/DocumentLargeGroup.htm > > However, you can also query for all objects that have the group DN in the > memberOf attribute. Instead of one row with thousands of values, you get a > recordset with thousands of rows. You just need to use paging if you > enumerate the recordset, but if all you need is the count you can use the > RecordCount property. In brief: > =========== > ' Specify Distinguished Name of the large group. > strGroupDN = "cn=Big Group,ou=Sales,dc=MyDomain,dc=com" > > ' Use ADO to search the domain for members of the group. > Set adoConnection = CreateObject("ADODB.Connection") > Set adoCommand = CreateObject("ADODB.Command") > adoConnection.Provider = "ADsDSOOBject" > adoConnection.Open "Active Directory Provider" > Set adoCommand.ActiveConnection = adoConnection > > ' Determine the DNS domain from the RootDSE object. > Set objRootDSE = GetObject("LDAP://RootDSE") > strDNSDomain = objRootDSE.Get("defaultNamingContext") > > ' Filter on all objects that are members of the group. > strFilter = "(memberOf=" & strGroupDN & ")" > > ' Construct the LDAP syntax query. > strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter _ > & ";distinguishedName;subtree" > > ' Run the query. > adoCommand.CommandText = strQuery > adoCommand.Properties("Page Size") = 100 > adoCommand.Properties("Timeout") = 30 > adoCommand.Properties("Cache Results") = False > Set adoRecordset = adoCommand.Execute > > ' Retrieve number of records. > strNumber = adoRecordset.RecordCount > Wscript.Echo "Number of members: " & strNumber > > ' Clean up. > adoRecordset.Close > adoConnection.Close > ============ > Or, you could enumerate the recordset with: > > ' Enumerate all members. > Set adoRecordset = adoCommand.Execute > Do Until adoRecordset.EOF > strDN = adoRecordset.Fields("distinguishedName").Value > Wscript.Echo strDN > adoRecordset.MoveNext > Loop > > But if you do both (enumerate and retrieve the count), you must use: > > adoRecordset.CursorType = 3 > > and after retrieving the count use: > > adoRecordset.MoveFirst > > before the loop to enumerate the recordset. However, I suspect you just want > the count. > > -- > Richard Mueller > Microsoft MVP Scripting and ADSI > Hilltop Lab - http://www.rlmueller.net > -- Such a crazy number makes me suspect a timeout. I would try increasing the
page size and the timeout. Perhaps: adoCommand.Properties("Page Size") = 900 adoCommand.Properties("Timeout") = 90 The max page size allowed is 1000, but most of the gain comes from turning it on. I increased the timeout from 30 to 90 seconds. I've seen a few cases where larger values (like 300) are needed, but that's when remote DC's are queried over slow links. This particular query should hit the nearest DC. Also, note the program retrieves 1000 values at a time. This is because the limit in Windows 2000 domain is 1000. The limit was increased to 1500 in W2k3. Maybe it would help to modify the code to retrieve 1500 values at a time. If the count is consistently 6110, I suspect a subtle ADO problem. In that case, I would try Joe Richards' free adfind utility to see it works better. http://www.joeware.net/win/free/tools/adfind.htm Let me know if the code to retrieve RecordCount works. Show quote "Sport" <keith.matth***@gmail.com> wrote in message news:1175206836.510599.258030@e65g2000hsc.googlegroups.com... > Thanks Richard! > The first thing I did was run your ADO Large Group and it stops at > 6110 for whatever reason. > ldifde works but is not great looking. > > Will try below, thanks again. > > Richard Mueller [MVP] wrote: >> Sport wrote: >> >> > Need a count of users/computers in a group membership that is upwards >> > of 13-15k accounts. >> > >> > ADSI is no go and stops at 1500 >> > ADO putters out at 6110 >> > csvde dies at 1500 as well >> > ldifde gets a bit more, at least 10k, but the format is terrible. >> > >> > Don't really need a long list would be happy with just a echo of the >> > number of accounts in group. >> > >> >> To document groups with more than 1500 members you have to use ADO range >> limits to retrieve all values of the member attribute of the group. I >> have a >> sample VBScript that uses this technique to document large groups linked >> here: >> >> http://www.rlmueller.net/DocumentLargeGroup.htm >> >> However, you can also query for all objects that have the group DN in the >> memberOf attribute. Instead of one row with thousands of values, you get >> a >> recordset with thousands of rows. You just need to use paging if you >> enumerate the recordset, but if all you need is the count you can use the >> RecordCount property. In brief: >> =========== >> ' Specify Distinguished Name of the large group. >> strGroupDN = "cn=Big Group,ou=Sales,dc=MyDomain,dc=com" >> >> ' Use ADO to search the domain for members of the group. >> Set adoConnection = CreateObject("ADODB.Connection") >> Set adoCommand = CreateObject("ADODB.Command") >> adoConnection.Provider = "ADsDSOOBject" >> adoConnection.Open "Active Directory Provider" >> Set adoCommand.ActiveConnection = adoConnection >> >> ' Determine the DNS domain from the RootDSE object. >> Set objRootDSE = GetObject("LDAP://RootDSE") >> strDNSDomain = objRootDSE.Get("defaultNamingContext") >> >> ' Filter on all objects that are members of the group. >> strFilter = "(memberOf=" & strGroupDN & ")" >> >> ' Construct the LDAP syntax query. >> strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter _ >> & ";distinguishedName;subtree" >> >> ' Run the query. >> adoCommand.CommandText = strQuery >> adoCommand.Properties("Page Size") = 100 >> adoCommand.Properties("Timeout") = 30 >> adoCommand.Properties("Cache Results") = False >> Set adoRecordset = adoCommand.Execute >> >> ' Retrieve number of records. >> strNumber = adoRecordset.RecordCount >> Wscript.Echo "Number of members: " & strNumber >> >> ' Clean up. >> adoRecordset.Close >> adoConnection.Close >> ============ >> Or, you could enumerate the recordset with: >> >> ' Enumerate all members. >> Set adoRecordset = adoCommand.Execute >> Do Until adoRecordset.EOF >> strDN = adoRecordset.Fields("distinguishedName").Value >> Wscript.Echo strDN >> adoRecordset.MoveNext >> Loop >> >> But if you do both (enumerate and retrieve the count), you must use: >> >> adoRecordset.CursorType = 3 >> >> and after retrieving the count use: >> >> adoRecordset.MoveFirst >> >> before the loop to enumerate the recordset. However, I suspect you just >> want >> the count. >> >> -- >> Richard Mueller >> Microsoft MVP Scripting and ADSI >> Hilltop Lab - http://www.rlmueller.net >> -- > |
|||||||||||||||||||||||