Cool Sakari, if you don't mind I made some small mods to it. I have it preload the attributes and then the lookups go much faster. The modified script runs against my AD in about 11-12 seconds, the original would take 123 seconds (2 minutes 3 seconds). Still not quite as fast as a perl lookup version I have based on adfind, but definitely good enough[1].
joe [1] I hate waiting for things. ================ Updated Script ' ------------------------------------------------------------------------- ' Script by Sakari Kouti (see http://www.kouti.com) ' Modified May 14, 2005 by joe (www.joeware.net) ' You have a royalty-free right to use, modify, reproduce and distribute ' this script (and/or any modified version) in any way you find useful, ' provided that you agree that Addison-Wesley or Sakari Kouti has no ' warranty, obligations or liability for the script. If you modify ' the script, you must retain this copyright notice. ' ------------------------------------------------------------------------- Option Explicit Dim objDSE, objExtRights, objChild, i, j, strrightsGuid, strOut, GuidHash '===The Main Program=== Set objDSE = GetObject("LDAP://rootDSE") Set objExtRights = GetObject("LDAP://CN=Extended-Rights," & _ objDSE.Get("configurationNamingContext")) ' Populate GuidHash - Modification by joe - 05/14/2005 set GuidHash=CreateObject("Scripting.Dictionary") LoadGuidHash() i = 0 For Each objChild In objExtRights If objChild.Class = "controlAccessRight" Then 'actually all should be this class If objChild.validAccesses And &H30 Then i = i + 1 WScript.Echo i & ": " & objChild.displayName 'WScript.Echo i & ": " & objChild.Name & ":" & objChild.rightsGuid & ":" & objChild.displayName strrightsGuid = objChild.rightsGuid MapGUIDToMatchingName("{" & strrightsGuid & "}") WScript.Echo vbTab & strOut End If End If Next '===End of the Main Program=== '============================== ' ' New sub added by joe - 05/14/2005 ' Took old MapGUIDToMatchingName and wrapped most of the ' logic into this sub and stuff info in hash/dictionary ' Sub LoadGuidHash() Dim objExtRights, objChild, objSchema, GUID, AttribInfo, fun, cnt Set objSchema = GetObject("LDAP://" & _ objDSE.Get("schemaNamingContext")) fun=Array(".","|","/","-","\","|","/","-","*") cnt=1 wscript.echo "Loading attributes..." objSchema.Filter = Array("attributeSchema") For Each objChild In objSchema GUID=UCase(GetSchemaIDGUID(objChild)) wscript.StdOut.write fun((cnt mod ubound(fun))) & VbCr cnt=cnt+1 if GUID<>"ABC" then AttribInfo=objChild.Get("cn") & ":" & objChild.Get("lDAPDisplayName") If GuidHash.exists(GUID) then GuidHash.Item(GUID) = GuidHash.Item(GUID) & ";" _ & AttribInfo else GuidHash.Add GUID,AttribInfo End If End If Next wscript.echo "Attribute load complete." wscript.echo End Sub ' ' Modified by joe - 05/14/2005 ' Sub MapGUIDToMatchingName(strGUIDAsString) Dim GUID, AttribInfo, Attrib, Attribs, vals GUID=UCase(strGUIDAsString) If GuidHash.exists(GUID) then AttribInfo=GuidHash.Item(GUID) Attribs=split(AttribInfo,";") For Each Attrib in Attribs vals=split(Attrib,":") WScript.Echo vbTab & vals(0) & vbTab & vals(1) Next else WScript.Echo vbTab & "No Properties" End If End Sub '============================== Function GetSchemaIDGUID(objSchemaObj) Dim arrValue, i, strByte, strGUID On Error Resume Next Err.Clear arrValue = objSchemaObj.Get("attributeSecurityGUID") If Err <> 0 Then GetSchemaIDGUID = "abc" Exit Function End If strGUID = "" For i = 1 to LenB(arrValue) strByte = Hex(AscB(MidB(arrValue, i, 1))) If Len(strByte) = 1 Then strByte = "0" & strByte strGUID = strGUID & strByte Next GetSchemaIDGUID = GuidBinFormatToStrFormat(strGUID) End Function '============================== Function GUIDBinFormatToStrFormat(strGUIDBin) Dim i, strDest Dim arrBytes(16) 'We will use elements 1 to 16 but not 0 For i = 1 To 16 'A GUID has 16 bytes arrBytes(i) = Mid(strGUIDBin, 2 * i - 1, 2) Next strDest = "{" For i = 1 To 4 : strDest = strDest & arrBytes(5 - i) : Next strDest = strDest & "-" For i = 1 To 2 : strDest = strDest & arrBytes(7 - i) : Next strDest = strDest & "-" For i = 1 To 2 : strDest = strDest & arrBytes(9 - i) : Next strDest = strDest & "-" For i = 1 To 2 : strDest = strDest & arrBytes(8 + i) : Next strDest = strDest & "-" For i = 1 To 6 : strDest = strDest & arrBytes(10 + i) : Next strDest = strDest & "}" 'WScript.Echo "attrSeGuid: " & strDest GuidBinFormatToStrFormat = strDest End Function -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Sakari Kouti Sent: Thursday, May 12, 2005 10:23 AM To: ActiveDir@mail.activedir.org Subject: RE: [ActiveDir] [OnTopic] Active Directory Property Set Madness Now that Joe brought this up, I uploaded a script that does this enumeration on http://www.kouti.com/scripts.htm (at the bottom of the page). You need only end-user permissions to run this script. You could first run it in a clean forest and a clean forest with Ex2003 installed, to get a reference. Then run it in the customer network and use windiff or whatever to pinpoint differences from the clean install. Yours, Sakari List info : http://www.activedir.org/List.aspx List FAQ : http://www.activedir.org/ListFAQ.aspx List archive: http://www.mail-archive.com/activedir%40mail.activedir.org/