10900 » How can I return all the user names in my domain, sorted by DN within Container and/or OU in a CSV format? (12-Oct-06)
I had scripted SortADU.bat to return all the
user names in my domain, sorted by distinguishedName within Container and/or OU .
Modifying a script by Richard Mueller, Hilltop Lab , I have scripted UsersByOU.vbs to
return a semi-colon delimited output that contains:
"The parent OU or container";"distinguishedName";"sAMAccountName"
Like:
"CN=Users,DC=JSIINC,DC=COM";"CN=Jerold Schulman,CN=Users,DC=JSIINC,DC=COM";"Jerry"
"OU=OU_TEST,DC=JSIINC,DC=COM";"CN=First Last,OU=OU_TEST,DC=JSIINC,DC=COM";"LastF"
To redirect the output to a file, use:
cscript //nologo C:\Folder1\UsersByOU.vbs > c:\Folder2\report.txt
UsersByOU.vbs contains:
Option Explicit
Dim objRootDSE, strDNSDomain, objCommand, objConnection
Dim strBase, strFilter, strAttributes, strQuery, objRecordSet
Dim strNTName, strDN, strParent, intLevel
Dim objDataList, intIndex1, intIndex2, intIndex3
Const adVarChar = 200
Const adInteger = 3
Const MaxCharacters = 255
' Determine DNS domain name.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
' Use ADO to search Active Directory.
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection
' Search entire domain.
strBase = ""
' Filter on all user objects.
strFilter = "(&(objectCategory=person)(objectClass=user))"
' Comma delimited list of attribute values to retrieve.
strAttributes = "sAMAccountName,distinguishedName"
' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
' Run the query.
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False
Set objRecordSet = objCommand.Execute
' Setup disconnected recordset.
Set objDataList = CreateObject("ADODB.Recordset")
objDataList.Fields.Append "NTName", adVarChar, MaxCharacters
objDataList.Fields.Append "DN", adVarChar, MaxCharacters
objDataList.Fields.Append "Parent", adVarChar, MaxCharacters
objDataList.Fields.Append "Level", adInteger
objDataList.Open
' Enumerate recordset returned by query.
Do Until objRecordSet.EOF
' Retrieve attribute values.
strNTName = objRecordset.Fields("sAMAccountName").Value
strDN = objRecordset.Fields("distinguishedName").Value
' Determine DN of parent container.
intIndex1 = InStr(LCase(strDN), ",cn=")
intIndex2 = InStr(LCase(strDN), ",ou=")
intIndex3 = InStr(LCase(strDN), ",dc=")
If (intIndex1 > 0) Then
' Parent container is a container.
strParent = Mid(strDN, intIndex1 + 1)
ElseIf (intIndex2 > 0) Then
' Parent container is an OU.
strParent = Mid(strDN, intIndex2 + 1)
Else
' Parent container is the domain.
strParent = Mid(strDN, intIndex3 + 1)
End If
' Determine hierarchical level in AD.
intLevel = 0
Call ADLevel(strParent)
' Add values for each user to disconnected recordset.
objDataList.AddNew
objDataList("NTName") = objRecordset.Fields("sAMAccountName").Value
objDataList("DN") = objRecordset.Fields("distinguishedName").Value
objDataList("Parent") = strParent
objDataList("Level") = intLevel
objDataList.Update
objRecordSet.MoveNext
Loop
' Sort the disconnected recordset by hierarchical level in AD,
' by parent container/OU name, and NTName
objDataList.Sort = "Level,Parent,DN,NTName"
' Enumerate the disconnected recordset.
objDataList.MoveFirst
Do Until objDataList.EOF
strNTName = objDataList.Fields.Item("NTName")
strParent = objDataList.Fields.Item("Parent")
strDN = objDataList.Fields.Item("DN")
Wscript.Echo """" & strParent & """;""" & strDN & """;""" & strNTName & """"
objDataList.MoveNext
Loop
' Clean up.
objRecordset.Close
objDataList.Close
objConnection.Close
Set objRootDSE = Nothing
Set objCommand = Nothing
Set objConnection = Nothing
Set objRecordSet = Nothing
Set objDataList = Nothing
Sub ADLevel(strParentDN)
' Recursive subroutine to determine hierachical level in AD.
' intLevel must be declared with global scope.
Dim intIndex
intIndex = InStr(LCase(strParentDN), ",ou=")
If (intIndex > 0) Then
intLevel = intLevel + 1
Call ADLevel(Mid(strParentDN, intLevel + 4))
Exit Sub
End If
intIndex = InStr(LCase(strParentDN), ",dc=")
If (intIndex > 0) Then
intLevel = intLevel + 1
Call ADLevel(Mid(strParentDN, intLevel + 4))
Exit Sub
End If
End Sub
End of Article