Previous Section Table of Contents Next Section

Putting It All Together

One potential use for domain- and OU-manipulation scripts is to configure a test or pilot domain that resembles your production domain. By using a script, you can install a domain controller in a lab, and then quickly recreate aspects of your production environment, such as OU structure and user accounts.

graphics/arrow.gif Preload Domain

Listing 15.1 shows a script that preloads a domain with a specific OU structure. Just for fun, I've thrown in a couple of new methods that copy and move OUs around within the domain. See if you can figure out how they work before you read the line-by-line explanation.

Listing 15.1. PreLoad.vbs. Preloads a specific OU configuration into a domain via LDAP.

'bind to domain

Dim oDomain

Set oDomain = GetObject("LDAP://dc=domain,dc=com")



'Create top-level OUs

Dim oSales, oHR, oMIS

Set oSales = oDomain.Create("organizationalUnit", "Sales")

Set oHR = oDomain.Create("organizationalUnit", "HR")

Set oMIS = oDomain.Create("organizationalUnit", "MIS")

oDomain.SetInfo



'set descriptions

oSales.Put "description", "Sales OU"

oHR.Put "description", "HR OU"

oMIS.Put "description", "MIS OU"

'save

oSales.SetInfo

oHR.SetInfo

oMIS.SetInfo



'create child OUs for Sales

Dim oChild

Set oChild = oSales.Create("organizationalUnit", "Widgets")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", "Wodgets")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", "Worm Gears")

oChild.SetInfo



'create child OUs for HR

Set oChild = oSales.Create("organizationalUnit", "Recruiting")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", "Counseling")

oChild.SetInfo



'create child OUs for MIS

Set oChild = oSales.Create("organizationalUnit", "Engineering")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", "Desktop")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", _

 "Configuration")

oChild.SetInfo



'set domain-wide password policy

oDomain.Put "minPwdLength", 10

oDomain.Put "maxPwdAge", 30

oDomain.Put "minPwdAge", 2

oDomain.SetInfo



'display contents of Users

Dim sContents, oUsers, oObject

Set oUsers = GetObject("LDAP://cn=Users,dc=domain,dc=com")

For Each oObject In oUsers

 sContents = sContents & oObject.Name & ", "

Next

WScript.Echo "Users contains: " & sContents



'create another top-level OU

Dim oOU

Set oOU = oDomain.Create("organizationalUnit", "Management")

oDomain.SetInfo



'move the top-level OU into Sales

oSales.MoveHere "LDAP://ou=Management,dc=domain,dc=com"



'create a management OU in HR, too

Dim oCopy

oCopy = oHR.Create("organizationalUnit", "Management")

oCopy.SetInfo



'now we're going to copy the Sales Management OU

'attributes to the HR Management OU

Dim oTemplate, aAttributes, sAttribute, sValue



'use the Sales OU as a reference

Set oTemplate = GetObject( _

 "LDAP://ou=Management,ou=Sales,dc=domain,dc=com")

aAttributes = Array("description", "location")



'copy each attribute from the source to the target

For Each sAttribute In aAttributes

 sValue = oTemplate.Get(sAttribute)

 oCopy.Put sAttribute, sValue

Next



'save the information

oCopy.SetInfo

Before you run this script, you obviously need to modify the LDAP connection strings to point to a domain in your environment. Of course, I highly recommend the use of a test domain, not your production domain!

graphics/arrow.gif Preload Domain-Explained

This script begins by binding to the domain itself.


'bind to domain

Dim oDomain

Set oDomain = GetObject("LDAP://dc=domain,dc=com")

Then, the script creates three top-level OUs: Sales, HR, and MIS. These are each referenced by their own object variables.


'Create top-level OUs

Dim oSales, oHR, oMIS

Set oSales = oDomain.Create("organizationalUnit", "Sales")

Set oHR = oDomain.Create("organizationalUnit", "HR")

Set oMIS = oDomain.Create("organizationalUnit", "MIS")

oDomain.SetInfo

The script then sets a description for each new OU.


'set descriptions

oSales.Put "description", "Sales OU"

oHR.Put "description", "HR OU"

oMIS.Put "description", "MIS OU"

Next, I save the information using the SetInfo method of each new OU.


'save

oSales.SetInfo

oHR.SetInfo

oMIS.SetInfo

Now, I create three child OUs under the Sales OU. After creating each, I save it, so that I can reuse the oChild object.


'create child OUs for Sales

Dim oChild

Set oChild = oSales.Create("organizationalUnit", "Widgets")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", "Wodgets")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", "Worm Gears")

oChild.SetInfo

Now the script creates two child OUs for HR, and three more under MIS. Again, notice the use of SetInfo after each call to Create.


'create child OUs for HR

Set oChild = oSales.Create("organizationalUnit", "Recruiting")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", "Counseling")

oChild.SetInfo



'create child OUs for MIS

Set oChild = oSales.Create("organizationalUnit", "Engineering")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", "Desktop")

oChild.SetInfo

Set oChild = oSales.Create("organizationalUnit", _

 "Configuration")

oChild.SetInfo

Now I return to the top-level domain object to set a few domain-wide password policy attributes. I've used Put to set each one, and then called SetInfo to save the new configuration.


'set domain-wide password policy

oDomain.Put "minPwdLength", 10

oDomain.Put "maxPwdAge", 30

oDomain.Put "minPwdAge", 2

oDomain.SetInfo

Just for fun, I have the script iterate through each object in the built-in Users container. Remember: Although it looks like an OU, it isn't one, so it has to be accessed by using the CN component, not the OU component. The result should be a comma-separated list of the object names in the container.


'display contents of Users

Dim sContents, oUsers, oObject

Set oUsers = GetObject("LDAP://cn=Users,dc=domain,dc=com")

For Each oObject In oUsers

 sContents = sContents & oObject.Name & ", "

Next

WScript.Echo "Users contains: " & sContents

Next, I create another top-level OU.


'create another top-level OU

Dim oOU

Set oOU = oDomain.Create("organizationalUnit", "Management")

oDomain.SetInfo

The script now moves the new OU to be a child OU of Sales. I could have created the OU directly under Sales, but that wouldn't have shown off the MoveHere method. Notice how this works: I use the MoveHere method of the parent object, specifying the LDAP string of the object to be moved. There's no need to call SetInfo in this case.


'move the top-level OU into Sales

oSales.MoveHere "LDAP://ou=Management,dc=domain,dc=com"

Now I want to copy the Sales/Management OU into HR, so that there will also be an HR/Management OU. I want the attributes of both OUs to be the same. I have to start by creating the new child OU under HR.


'create a management OU in HR, too

Dim oCopy

oCopy = oHR.Create("organizationalUnit", "Management")

oCopy.SetInfo

I need a reference to my template object, which is the Management OU that already exists under the Sales OU.


'now we're going to copy the Sales Management OU

'attributes to the HR Management OU

Dim oTemplate, aAttributes, sAttribute, sValue



'use the Sales OU as a reference

Set oTemplate = GetObject( _

 "LDAP://ou=Management,ou=Sales,dc=domain,dc=com")

aAttributes = Array("description", "location")

Next, I can use a For Each…Next loop to copy each attribute from Sales/Management to HR/Management.


'copy each attribute from the source to the target

For Each sAttribute In aAttributes

 sValue = oTemplate.Get(sAttribute)

 oCopy.Put sAttribute, sValue

Next

When the attributes are copied, a call to SetInfo saves the changes.


'save the information

oCopy.SetInfo

Using this type of script to quickly load a domain is a valuable trick, and can save you many hours in the test lab. Unlike a backup, which always restores the same thing, this script can be easily tweaked to set up different test environments, or to reflect changes in your production domain.

    Previous Section Table of Contents Next Section