Guy’s Scripting Ezine 123 – ‘Walking the AD Tree’

Guy’s Scripting Ezine 123 – ‘Walking the AD Tree’


This Week’s Secret

If you create your own scripts then you will know that euphoric feeling when you make a breakthrough and the script performs its magic.  Could this feeling of discovery have been more intense for Einstein or Archimedes?  I doubt it.  That said, I would the first to point out that my humble script is not within a light year of their awesome achievements.  But what I would say to you is this: ‘Keep on scripting, success is a powerful drug’.

This Week’s Mission

I would like to thank DA and Sean Hook for their support in developing this week’s script.  This was true role reversal, instead of me helping others get started, it was they who showed me the way to fulfil my mission and create a script which ‘Walks the Active Directory tree’.

Briefly, here is the mission:

We have an existing script that modifies the value of users properties.  For example, it resets the password for all those user accounts whose LDAP property ‘Description’ = "Year 1".

Jolly good, so what’s the problem then?  The problem is that the script writes to objects in just one named container object.  In plain English, the script only works in one OU.  Now what our mission requires is code that will ‘Walk the AD Tree’ and thus work for all users in all OUs.

The eureka moment came to me when DA sent a script with this command:
strRoot.Filter = Array("OrganizationalUnit")

The significance of this one command is that I now have all the OUs in my grasp.  As usual, I will start gradually; in Example 1 we will merely count the OUs and not make any changes.  Once this works, we move to Example 2 where we add code which does LDAP ‘stuff’.  Stuff like changing passwords, adding values for a Location, or a search and replace on the value held in the LDAP ‘Department’ property.  To control this LDAP stuff centrally, I will indulge my passion for the Sub Routine.

Guy Recommends:  SolarWinds’ Free Bulk Import ToolFree Download Solarwinds Bulk Import Tool

Import users from a spreadsheet.  Just provide a list of the users with their fields in the top row, and save as .csv file.  Then launch this FREE utility and match your fields with AD’s attributes, click and import the users.

Optionally, you can provide the name of the OU where the new accounts will be born. Download your FREE bulk import tool.

If you need more comprehensive software, download a free trial of SAM (Server & Application Monitor)

Example 1 – To Walk the Active Directory Tree

You really do need an active directory domain for this VBScript to work.  I am also assuming that you are not one of those people who don’t create any OUs in their Active Directory.  In any case, after you run the script once you could add another OU and run the script again.


  1. Copy and paste the script below into notepad or get a script editor such as OnScript.
  2. Save the file with .vbs extension e.g. WalkADBas.vbs
  3. Double click your script and check the message box to see how many OUs you have in Active Directory.

‘ WalkADBas.vbs
‘ Example VBScript to ‘Walk the Active Directory Tree
‘ And echo the number of OUs
‘ Version 1.4 – September 2006
‘  ——————————————————–‘
Option Explicit

Dim objChild, objRootDSE
Dim strRoot, strDNSDomain, intCounter
intCounter = 0

Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
set strRoot =GetObject("LDAP://" & strDNSDomain )
‘  ——————————————————–
‘  Here is the crucial line:
strRoot.Filter = Array("OrganizationalUnit")
for each objChild in strRoot
    intCounter = intCounter +1
WScript.Echo "Number of OUs = " & intCounter


VBScript Learning Points

Note 1:  The crucial line is strRoot.Filter = Array("OrganizationalUnit").  Short, simple, but so powerful, what it does is extract all the OUs from the other Active Directory objects.  Thereafter the script employs a standard VBScript loop: for each…. next.

Note 2:  Lines 12-14 (count spaces and ‘Remarks) employ my standard technique to connect to the root of any Active Directory namespace.  There is no need in most of my scripts to type names such as dc=xyz,, because these three lines find the appropriate names automatically.

Note 3:  I stress, that to build up gradually, this script just counts the OUs.  My reasoning is that I want to put the microscope on the command: strRoot.Filter = Array("OrganizationalUnit").  Then you can use this as a skeleton for your scripts not just mine.  Let us go on to Example 2 where we perform some useful Active Directory tasks.

Guy Recommends:  A Free Trial of the Network Performance Monitor (NPM)Review of Orion NPM v11.5 v11.5

SolarWinds’ Orion performance monitor will help you discover what’s happening on your network.  This utility will also guide you through troubleshooting; the dashboard will indicate whether the root cause is a broken link, faulty equipment or resource overload.

What I like best is the way NPM suggests solutions to network problems.  Its also has the ability to monitor the health of individual VMware virtual machines.  If you are interested in troubleshooting, and creating network maps, then I recommend that you try NPM now.

Download a free trial of Solarwinds’ Network Performance Monitor

Example 2 – To Rest the Passwords for Accounts where Description = "Year 1"

The point of this script is to reset passwords.  However, to avoid annoying most of your users, it only changes those accounts whose description is Year 1.  Description is an LDAP field that you can see in any user property sheet in Active Directory Users and Computers.


I almost always prefer scripts that perform a real job and I almost always avoid ‘Hello World’ examples.  The only problem of learning my way is that you have to keep alert for where you should change values, and where you must leave them as the original.  In this instance either change "Year 1" to some other phrase, or else deliberately add Year 1 to the description of some of your users.  By all means create a special test OU just to test this script.

I strongly suggest that you master this script first

‘ WalkAD.vbs
‘ Example VBScript to ‘Walk the Active Directory Tree
‘ And then change a user’s password
‘ Version 2.3 – August 2006
‘ ———————————————————‘
Option Explicit

Dim objUser, objChild, objConnection, objRootDSE
Dim strRoot, strDNSDomain, strContainer, strPassword
Dim intAccValue, intCounter, intPwdValue

‘ ———————————————————
strPassword = "F@rst0ne"
intAccValue = 544
intPwdValue = 0
intCounter = 0

Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
strContainer = strContainer & strDNSDomain
set strRoot =GetObject("LDAP://" & strDNSDomain )
‘ ———————————————————–

strRoot.Filter = Array("OrganizationalUnit")
for each objChild in strRoot
Call DATree()

sub DATree()
For each objUser in objChild
If objUser.class="user" then
      If objUser.Description ="Year 1" then
      objUser.SetPassword strPassword
      objUser.Put "pwdLastSet", intPwdValue
      objUser.Put "userAccountControl", intAccValue
      intCounter = intCounter +1
      End If
End if
End Sub

Wscript.Echo "Accounts changed = " & intCounter

Learning Points

Note 1:  There are two main changes compared with example 1.  At the bottom of the script is a sub routine.  Once my example works, it would give me great satisfaction if you amended the code to suit your Active Directory tasks.

The other change is the Call statement : Call DATree().

Note 2:  It’s confession time.  This script has a terrible flaw, it only works for one level of OU.  It won’t drill down to nested OUs.  Good news DA, not only spotted the fault, but also provided the code to correct the problem.  It’s a bit mean I know, but you will have to wait for next week to get the extra code.  Meanwhile, I challenge you to use my script as a test bed for trying out your ideas.

Guy Recommends: Tools4ever’s UMRAUMRA The User Management Resource Administrator

Tired of writing scripts? The User Management Resource Administrator solution by Tools4ever offers an alternative to time-consuming manual processes.

It features 100% auto provisioning, Helpdesk Delegation, Connectors to more than 130 systems/applications, Workflow Management, Self Service and many other benefits. Click on the link for more information onUMRA.

Guy’s Challenges

Challenge 1:   Add more users with "Year 2" in their descriptions.  See if you can change the script to reset their passwords.

Challenge 2:   Select different LDAP fields, for example DisplayName or sn, but be careful, don’t get too carried away.

Challenge 3:  Instead of resetting passwords, make the script alter the Description, for example change all ‘Year 1’ to ‘Year 2’.

Summary of  Walking the Active Directory Tree

Getting a script to read not just one but all OUs was immensely satisfying, more so because of the help that I got from DA and Sean.  Confession time, this ‘Walking the Active Directory Tree’ script has a fatal flaw, it only looks at top level OUs.  However, next week thanks to DA we will improve on the script, and thus enable it to check all OUs no matter how deep the nesting.

See More Active Directory VBScripts featuring Active Directory

• Create Users  •PB 55 CSVDE  • Ezine 56 OU  • Ezine 123 Ad Tree  •Ezine 124 Ad Tree  •IPAM 3 Review

Ezine 23 enable accounts  •UserAccountControl Values  •Ezine 27 Move Computers  • Ezine 42 LDAP

Ezine 44 CSVDE  • Ezines  • PowerShell Add Computer  • LDAP Properties  • Free CSVDE Importer