Scripting Active Directory

I seem to have been dong a lot of scripting work recently – I really should be using PowerShell, but I had limited time to get this stuff done and it needed to pretty generic / simple as it would be implemented by others (some with limited knowledge of scripting / coding)..

Anyway, the requirement was to ‘shlurp’ all the users from areas of Active Directory for use with one of our products. I wanted to get all users in specific AD containers into a dictionary object so that I could use them later…

The containers I looked at were :-

  • Organizational Units (OUs) – needed to be recursive to pull in sub OUs
  • Distribution Lists (DLs) – also needed to be recursive to pull in sub DLs
  • Query Based Distribution Lists
  • Users with a mailbox on a particular server.

The code is below. One of the keys to this is using LDP.exe to get the LDAP DNs for the various containers/lists….

Set objDictionary = CreateObject(“Scripting.Disctionary”) GetAllMembersFromOU “OU=Reading,OU=UK,DC=YOURDOMAIN,DC=COM”, objDictionary GetAllMembersFromDL “DN=UK_Sales,OU=UK,DC=YOURDOMAIN,DC=COM”, objDictionary GetAllMembersFromQueryBasedDL “DN=CRMUsers,OU=UK,DC=YOURDOMAIN,DC=COM”, objDictionary

strHomeServer = “/o=ABC Systems/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=EX-01”
GetAllMembersFromServer strHomeServer, objDictionary

’ Write the found users out to a text file
WriteDictionaryToTextFile objDictionary, “c:ad_users.txt”

‘ BELOW ARE THE FUNCTIONS THAT DO THE WORK

’****************************************************************** ‘ GetAllMembersFromOU ‘ ‘ Gets all the members of an OU (including sub OUs) and adds them to a dictionary object ‘ ‘ sDN - a string containing the DN of the OU to start from (e.g. “LDAP://OU=Reading,OU=UK,DC=YOURDOMAIN,DC=COM”) ‘ dic - a ‘Scripting.Dictionary’ object that you want to hold all the objects in. ‘ ‘ ‘ Ken Hughes 10 July 2007 ‘****************************************************************** Function GetAllMembersFromOU(sDN, dic)

Set objOU = GetObject("LDAP://" & sDN)

For each objMember in ObjOU

    Select Case LCase(objMember.Class)

        case "organizationalunit"
            GetAllMembersFromOU objMember.ADSPath, dic

        case "user"
            AddUserToDictionary dic, objMember

        case else
            ' do nothing it was a strange class
    End Select

Next

End Function

’****************************************************************** ‘ GetAllMembersFromDL ‘ ‘ Gets all the members of a distribution list (including sub DLs) and adds them to a dictionary object ‘ ‘ sDN - a string containing the DN of the OU to start from (e.g. “LDAP://OU=Reading,OU=UK,DC=YOURDOMAIN,DC=COM”) ‘ dic - a ‘Scripting.Dictionary’ object that you want to hold all the objects in. ‘ ‘ ‘ Ken Hughes 10 July 2007 ‘****************************************************************** Function GetAllMembersFromDL(sDL, dic)

Set objOU = GetObject("LDAP://" & sDL)

For each objMember in ObjOU.Members

    Select Case LCase(objMember.Class)

        case "group"
            GetAllMembersFromDL objMember.ADSPath, dic

        case "user"
            AddUserToDictionary dic, objMember

        case else
            ' do nothing it was a strange class

    End Select

Next

End Function

’****************************************************************** ‘ GetAllMembersFromServer ‘ ‘ Gets all the users who have mailboxes homed on a particular server ‘ ‘ sDN - a string containing the msExchHomeServerName
‘ (e.g. “LDAP:///o=ABC Systems/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=EX-01”) ‘ dic - a ‘Scripting.Dictionary’ object that you want to hold all the objects in. ‘ ‘ ‘ Ken Hughes 10 July 2007 ‘****************************************************************** Function GetAllMembersFromServer(sDN, dic)

set conn = createobject("ADODB.Connection")
Set iAdRootDSE = GetObject("LDAP://RootDSE")
strDefaultNamingContext = iAdRootDSE.Get("defaultNamingContext")
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"

strQueryDL = "<LDAP://" & strDefaultNamingContext & ">;(&(msExchHomeServerName=" & sDN   
strQueryDL = strQueryDL & ")(objectCategory=person)(objectClass=user));distinguishedName,adspath;subtree"
set objCmd = createobject("ADODB.Command")
objCmd.ActiveConnection = Conn
objCmd.Properties("SearchScope") = 2 ' we want to search everything
objCmd.Properties("Page Size") = 500 ' and we want our records in lots of 500

objCmd.CommandText = strQueryDL
Set objRs = objCmd.Execute

While Not objRS.eof

    Set objMember = GetObject("LDAP://" & replace(objRS.Fields("distinguishedName"),"/","/"))

        Select Case LCase(objMember.Class)

            case "user"
                AddUserToDictionary dic, objMember

            case else
                ' do nothing it was a strange class

        End Select

    objRS.MoveNext
Wend

End Function

’****************************************************************** ‘ GetAllMembersFromQueryBasedDL ‘ ‘ Gets all the members of a query based distribution list ‘ ‘ sDN - a string containing the DN of the QBDL (e.g. “LDAP://DL=AdminUsers,OU=Reading,OU=UK,DC=YOUROMAIN,DC=COM”) ‘ dic - a ‘Scripting.Dictionary’ object that you want to hold all the objects in. ‘ ‘ ‘ Ken Hughes 10 July 2007 ‘****************************************************************** Function GetAllMembersFromQueryBasedDL(sDN, dic)

set conn = createobject("ADODB.Connection")
Set iAdRootDSE = GetObject("LDAP://RootDSE")
strDefaultNamingContext = iAdRootDSE.Get("defaultNamingContext")
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"

Set objQBDL = GetObject("LDAP://" & sDN)

strQueryDL = "<LDAP://" & objQBDL.msExchDynamicDLBaseDN & ">;" & objQBDL.msExchDynamicDLFilter  
strQueryDL = strQueryDL & ";mail,ObjectClass,distinguishedName,displayname,legacyExchangeDN,homemdb;subtree"
set objCmd = createobject("ADODB.Command")
objCmd.ActiveConnection = Conn
objCmd.Properties("SearchScope") = 2 ' we want to search everything
objCmd.Properties("Page Size") = 500 ' and we want our records in lots of 500

objCmd.CommandText = strQueryDL
Set objRs = objCmd.Execute

While Not objRS.eof

    Set objMember = GetObject("LDAP://" & replace(objRS.Fields("distinguishedName"),"/","/"))

        Select Case LCase(objMember.Class)

            case "user"
                AddUserToDictionary dic, objMember

            case else
                ' do nothing it was a strange class

        End Select

    objRS.MoveNext
Wend

End Function ‘****************************************************************** ‘ WriteDictionaryToTextFile ‘ ‘ Writes the contents of a dictionary object to a text file ‘ ‘ objDic - a ‘Scripting.Dictionary’ object that holds all the objects you want written to the file ‘ fileName - a string containing the name of the file you want the objects written out to. ‘ ‘ ‘ Ken Hughes 10 July 2007 ‘****************************************************************** Sub WriteDictionaryToTextFile(objDic, fileName)

Dim objFSO, objFile
Const forReading = 1
Const forWriting = 2
Const forAppending = 8

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(filename, forWriting, True)

For Each obj in objDic.Keys
    objFile.Writeline obj
Next
objFile.Close
Set objFile = Nothing
Set objFSO = Nothing End Sub

GEO 51.4043197631836:-1.28760504722595