PowerShell Ezine, Logon Scripts

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.

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.

Instructions

  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
next
WScript.Echo "Number of OUs = " & intCounter

Wscript.Quit
 

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,dc.com, 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.

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.

Pre-requisites

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()
next

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

Wscript.Echo "Accounts changed = " & intCounter
Wscript.Quit


 

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.


If you are looking for handy network utilities, try some of the free downloads at Tools4Ever


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.

 

Computer Training Software - Recommended Training VideosGuy Thomas recommends Computer Training Software

Their topics and material are ideal for getting you started with VBScript.  The videos are easy to follow and you can control the pace.  Try their free demo material and then see if you want to buy the full package. See more about VB Script Training CD.


 

 *


Google

Web  This website

Guy Recommends: SolarWinds Engineer's Toolset v10Engineer's Toolset v10

The Engineer's Toolset v10 provides a comprehensive console of utilities for troubleshooting computer problems.

There are so many good gadgets, it's like having free rein of a sweetshop. Thankfully the utilities are displayed logically: monitoring, discovery, diagnostic, and Cisco tools.  Download your copy of the Engineer's Toolset v 10

 

Home Copyright © 1999-2010 Computer Performance LTD All rights reserved.

Please report a broken link, or an error.