Some Easy Active Directory Scripting

I solved a little problem for a customer the other day and I thought I'd share a little about it with you. It involves some VBScript user manipulation in Active Directory, and yes: there will be a code sample.

Let's start with the problem. For whatever reason, some users were missing some home drive information and more than half of users were not configured for roaming profiles. It was determined that this should be corrected. An easy way, of course, would be to push a group policy out which would configure something like: \\servername\home\%username% for home directory paths and \\servername\profile\%username% for profile paths. Well, that would have been easy if that's what the customer wanted to do, but it wasn't. Instead, they have set up a rather nice DFS root share for home drives and profile paths broken down by, lets say, users' last names. Sample paths for this would be \\\home\%x\%username% where %x is the user's first initial of the last name. This wouldn't be so easy with a group policy. So for this, I wrote some code.

What I did was obtain a list of users who needed these properties set in display name format. This was done by extracting user information with CSVDE. The result would look something like this:

Smith, Bob
Johnson, William K.

Once I had this file (named users.txt), I could run my script

If you'll notice, in this particular instance, the display name is Last, First. Many corporations configure their GAL this way, and I can understand why, although at Microsoft we use the reverse order of First Last.

What the script does is open a log file for writing, open the users.txt file for reading

 Const ForWriting = 2
Const ForReading = 1

'Path for log
logfilepath = "C:\TEMP\log.txt"

'Path for user list
userfilepath = "C:\TEMP\users.txt"

'Base Paths
baseHomePath = \\\home\baseProfilePath = \\\profile\

'Setup input file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInputFile = objFSO.OpenTextFile(userfilepath, ForReading, True)

'Setup log file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objAdLogTextFile = objFSO.OpenTextFile(logfilepath, ForWriting, True)

'Create Objects for LDAP Queries
Set rootDSE = GetObject("LDAP://RootDSE")
DomainContainer = rootDSE.Get("defaultNamingContext")

Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADSDSOObject"
conn.Open "ADs Provider"

'Read in username from input file
Do Until objInputFile.AtEndOfStream

  strDisplayName = objInputFile.Readline

  'Find all users in AD using an LDAP query
  strLDAP = "<LDAP://" & DomainContainer & ">;(&(objectCategory=person)(objectClass=user)_
      (anr=" & strDisplayName & "*));adspath;subtree"

  'Get query results and output to file
  Set oComm = CreateObject("ADODB.Command")
  oComm.ActiveConnection = conn
  oComm.CommandText = strLDAP
  oComm.Properties("Sort on") = "displayName" 
  oComm.Properties("Page size") = 15000

  set rs = oComm.Execute
  If rs.recordcount = 0 then 
        QueryResult = "User not found" 
        objAdLogTextFile.WriteLine(FoundObject.Displayname & " | " & QueryResult)  
  End If 

  If rs.recordcount > 1 then 
        QueryResult = "Resolved to more than one name" 
        objAdLogTextFile.WriteLine(FoundObject.Displayname & " | " & QueryResult) 
  End If 

  If rs.recordcount = 1 then 
    While Not rs.EOF
      Set FoundObject = GetObject (rs.Fields(0).Value)
      fullProfilePath = baseProfilePath & left(FoundObject.displayName,1) & "\" &_
      fullHomePath = baseHomePath & left(FoundObject.displayName,1) & "\" &_
      objAdLogTextFile.WriteLine(FoundObject.Displayname & " | " & fullHomePath &_
          " | " & fullProfilePath)
      FoundObject.profilePath = fullProfilePath
      FoundObject.homeDirectory = fullHomePath
      FoundObject.homeDrive = "H:"
  End if
MsgBox "Processing complete!"

This code helped me to set the baseline for existing users. New would then need to be created with the proper home drive and profile path. A good way to automate this is with something like ILM to provision user accounts. ILM is good for quite a lot of things and maybe one day, I'll have some tidbits to post about it.

Until next time, I hope this sample will help you get started on your own scripts for your directory.