Tutorial for Creating an OU (Organizational Unit) with VBScript
When I visit companies, it surprises me that only
50% of network managers create any OUs in their Active Directory. The rest keep all their accounts in the Users (or Computers) container.
The distinction between OU and container object is not just a matter of a strange book on the OU (see diagram
Accounts). OUs are great not only for organizing user
and computer accounts, but also OUs for making it easier to fine tune your group policies. (You cannot create or assign Group Policies to the Users or Computers containers.
The other
reason for getting the difference between OU and Container clear in your mind is when you start building Active Directory scripts. It is easy to make a mistake and try to script CN=Accounts, or
OU=Computers, when it should be OU=Accounts and CN=Computers.
Topics for Creating an OU (Organizational Unit) with VBScript
While we create OUs (Organizational Units) primarily as containers to organize users, let us take the opportunity and
learn about scripting commands such as: 'Set, Create(Object), Get(Object) and .SetInfo'.
The subsidiary reason for studying OUs is when you need to alter objects in that OU, when your script binds
not to the Users container but a named OU, you need to pay attention to detail as there are at least three traps for the unwary.
Please would you inspect Active Directory Users and Computers and confirm that there is no tiny book symbol on your Users folder. My point is that Users is a container object, referenced by
CN=Users, not an OU referred to by: OU=Users.
Meanwhile, back to the main goal, creating a top level OU with VBscript.
Instructions
Important: Which OU will create? My script will generate OU=Accounts. If you prefer a
different OU name, then change line 10 in your script.
Copy and paste the script below into notepad.
Save the file with .vbs extension e.g. Accounts.vbs.
Double click and examine the message boxes.
Open Up your Active Directory Users and Computers and inspect the OUs.
' VBscript to create an OU (Organizational Unit) ' Note two steps to set domain ' Author Guy Thomas http://computerperformance.co.uk/ ' Version 1.3 - September 2005 '
----------------------------------------------------------' Option Explicit Dim objRoot, objDomain, objOU Dim strContainer
strContainer ="OU=Accounts"
' Section to bind to YOUR Active
Directory. Set objRoot = GetObject("LDAP://rootDSE") objDomain = objRoot.Get("defaultNamingContext") Set objDomain = GetObject("LDAP://" & objDomain)
' Section to create the OU defined by
strContainer ' Also note the use of: .SetInfo
'On Error Resume next Set objOU = objDomain.Create("organizationalUnit", strContainer) objOU.SetInfo
WScript.Echo "New Top Level OU created
= " & strContainer WScript.quit
Learning Points - Binding to Active Directory
Building on this theme of mastering VBScript commands, I would like to draw your attention to a section of the script. What we see here is how VBScript binds to Active Directory. There has to
be a logical connection or binding before we can manipulate existing objects, or as here, create a new OU.
' Section to bind to YOUR Active Directory. Set objRoot = GetObject("LDAP://rootDSE") objDomain = objRoot.Get("defaultNamingContext") Set objDomain = GetObject("LDAP://" &
objDomain)
Note 1: GetObject() retrieves data, later in the full script we will make the OU with the sister command CreateObject()
Note 2: The 'Set' Command points the objRoot variable to the base of the LDAP name. Think of rootDSE as tunnelling down into the heart of Active Directory and returning with information. In
this instance, naming information.
Note 3: DefaultNamingContext is a wonderful command because I do not have to know your domain, the script retrieves the distinguished name automatically, for example dc=cp, dc=mosel.
(DC = Domain Context, not Domain Controller). The alternative would be to 'hard code' my
domain name, then ask you to search and replace with your domain. What a waste of time when I can use DefaultNamingContext.
Note 4: You may see other people's scripts, which Set ObjDomain with one line instead of two. My way just helps us understand the stages of binding to Active Directory.
Learning Points - Creating the actual OU
Here is the section which creates, and then saves the new OU.
strContainer ="OU=Accounts"
'On Error Resume next Set objOU = objDomain.Create("organizationalUnit", strContainer) objOU.SetInfo
Note 1: Guy loves variables, so here is the variable which holds the OU name: strContainer ="OU=Accounts"
Note 2: Spot the use of Set, as in Set objOU.
Note 3: What the script is saying is this, start with the domain (objDomain), now create a new OU (Not a user or a computer). And then the script extracts the name of the new OU from the
strContainer variable.
Note 4: Another member of the Set family is .SetInfo. Take special note of .SetInfo because overlooking this command can mean that the script runs silently without error, but nothing actually gets created.
The idea of this VBScript example is to create
a child OU. My assumption is that you have already made a parent or top level OU as described in Example1.
Creating a child OU is simple but there is a trap. Which of these two sequences should you use?
strContainer = parent, child. or strContainer = child, parent?
Assuming the parent is called Accounts, Here is the answer: strContainer ="OU=Child,OU=Accounts"
Tip: When scripting OUs pay particular attention to the placement of commas. To create a child OU we just need one comma in the string variable. (In other cases, but not here, we need two
commas.)
' VBSCript to create a child OU (Organizational Unit) ' Author Guy Thomas http://computerperformance.co.uk/ ' Version 2.3 - September 2005 '
----------------------------------------------------------' Option Explicit Dim objRoot, objDomain, objOU Dim strContainer err.number = vbEmpty
' Section to create the OU defined by
strContainer strContainer ="OU=Child,OU=Accounts"
' Section to bind to YOUR Active Directory. Set objRoot = GetObject("LDAP://rootDSE") objDomain = objRoot.Get("defaultNamingContext") Set
objDomain = GetObject("LDAP://" & objDomain)
On Error Resume next Set objOU = objDomain.Create("organizationalUnit", strContainer ) objOU.Put "Description", "Guy's OU" objOU.SetInfo
'
Confirmation Message If Err.Number = vbEmpty Then WScript.Echo "New Child OU created = " & strContainer Else WScript.Echo "Problem: " & err.number End If
WScript.Quit
Learning Points - Creating the Child OU
Note 1: The key amendment to this script is the strContainer variable. To create the child OU I amend to: strContainer ="OU=Child,OU=Accounts"
Note 2: I have added
primitive error-correcting code in preparation for Example 3.
I would like to anticipate what could go wrong. Specifically, I want the script to hand two situations: 1) Where the child OU already exists 2) The situation where there is no Parent OU
To handle the error I divided the OU path into strParent and strContainer.
Most of the error-correcting takes place in the subroutine called GuyError().
' VBSCript to create a child OU (Organizational Unit) ' With error-correcting code ' Author Guy Thomas http://computerperformance.co.uk/ ' Version 2.4 - September 2005 '
----------------------------------------------------------' Option Explicit Dim objRoot, objDomain, objOU Dim strContainer, strParent err.number = vbEmpty
' Section to bind to YOUR Active
Directory. Set objRoot = GetObject("LDAP://rootDSE") objDomain = objRoot.Get("defaultNamingContext") Set objDomain = GetObject("LDAP://" & objDomain)
' Section to create the OU defined by
strContainer strParent ="OU=Accounts" strContainer ="OU=Child," & strParent
On Error Resume next Set objOU = objDomain.Create("organizationalUnit", strContainer ) objOU.Put "Description",
"Guy's OU" objOU.SetInfo
' error-correcting Code If Err.Number <> vbEmpty Then Call GuyError Else WScript.Echo "New Child OU created = " & strContainer End If WScript.Quit(0)
' error-correcting code to create Parent OU Sub GuyError() If Err.number = "-2147019886" then Wscript.Echo "Child OU already created" WScript.Quit(1) Else Wscript.Echo "Error " &
Err.number Set objOU = objDomain.Create("organizationalUnit", strParent ) objOU.Put "Description", "Guy's Bulk Users OU" objOU.SetInfo Set objOU = objDomain.Create("organizationalUnit",
strContainer ) objOU.SetInfo WScript.Echo strParent & " Child and Parent OU Created " End If End Sub
Note 1: Firstly, I researched the err.number for situations where the OU already existed, it turn out that the number was -2147019886. You may be more familiar with this error as
WSH Error: 80071392.
Note 2: Trace how the sub GuyError makes use of strParent and strContainer.
It is surprising how often you need an OU. For example, testing Group Policies, testing Logon Scripts. There again, perhaps you just want a new OU for your accounts in Active Directory Users
and Computers.
My script will build your Active Directory Organizational Unit. All you need to do is adjust the variable:
strContainer = "OU = Accounts". If you have the time, then go through the script searching for all the script commands. Should there be any verbs that you do not understand, do refer to the learning points.
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.