Modifying the Address Tab Information
One of the more useful tasks you can perform with Active Directory is exposing address information. This ability is particularly important when a company has more than one location and more than a few hundred employees. I remember when one of the first uses for an intranet was to host a centralized list of employees. Such a project quickly paid for itself because companies no longer needed an administrative assistant to modify, copy, collate, and distribute hundreds of copies of the up-to-date employee directorypotentially a full-time job for one person. Once an intranet site was in place, personnel at each location were given rights to modify the list. With Active Directory, you avoid this duplication of work by keeping all information in a centralized location. The Address tab in Active Directory Users And Computers is shown in Figure 12-3.
In the ModifyUserAddressTab.vbs script, you use ADSI to set the street, post office box, city, state, zip code, c, co, and country values for the User object. Table 12-1 lists the Active Directory attribute names and their mappings to the Active Directory Users And Computers (ADUC) management tool "friendly" display names.
Table 12-1. Address Tab MappingsActive Directory Users And Computers label | Active Directory attribute name |
---|
Street | streetAddress | P.O. Box | postOfficeBox | City | l (note that this is lowercase L) | State/Province | st | Zip/Postal Code | postalCode | Country/Region | c,co,countryCode |
ModifyUserAddressTab.vbs
Option Explicit
On Error Resume Next
Dim strProvider 'defines how will talk
Dim strOU 'path to where new object will be created
Dim strDomain 'name of domain connecting to
Dim strOUName 'user name
Dim objUser 'holds connection to adsi
strProvider = "LDAP://"
strOU = "ou=mred,"
strDomain = "dc=nwtraders,dc=msft"
strOUName = "CN=myNewUser,"
Set objUser = GetObject(strProvider & strOUName & strOU & strDomain)
WScript.Echo strProvider & strOUName & strOU & strDomain ' debug info
objUser.Put "streetAddress", "123 main st"
objUser.Put "postOfficeBox", "po box 12"
objUser.Put "l", "Bedrock"
objUser.Put "st", "Arkansas"
objUser.Put "postalCode" , "12345"
objUser.Put "c", "US"
objUser.Put "co", "United States"
objUser.Put "countryCode", "840"
objUser.SetInfo
If Err.Number = 0 Then
WScript.Echo("User " & strOUName & " was modified")
Else
WScript.Echo "an error occurred. it was: " & Err.Number
End If
Reference Information
The Reference information section assigns values to the variables declared in the script. In this section, you assign the LDAP provider to the provider variable. You then build the entire OU path to the ou variable. The domain variable gets assigned both domain components and constructs a fully qualified name. You use strOUName to hold the user name you plan to modify.
Worker Information
The Worker information section begins by performing an Active Directory binding:
Set objUser = GetObject(strProvider & strOUName & strOU & strDomain)
The hardest part of the Worker information section of this script is figuring out how to make the country assignment show up in ADUC. I will admit that it took me a bit of time before I realized that the country codes have to be entered in accordance with International Organization for Standardization (ISO) standard 3166. If you use the c field, you use the two-letter country code. If you use ISO standard 3166-1, which contains two-letter country codes that have been officially assigned, you will be in fine shape. However, 3166-1 also contains country number assignments and short text names. The alternate forms of country codes do not work with the c field. ISO 3166 is actually divided into three different parts and is updated on a regular basis to keep up with global political changes. In compliance with ISO 3166, country codes can actually be entered in three different ways. The easiest to deal with uses the letter c as the field and a two-letter country code as the property.
Although ISO 3166-1 specifies all the country codes as uppercase letters, ADSI seems to be case-agnostic for this field, so us or US will both cause the field to display the name of United States. (One interesting thing about the ISO 3166-1 codes is that in most cases they are the same as the national top-level domain names.) A sample two-letter country code sheet based on ISO 3166-1 is listed in Table 12-2. The full table is available at http://www.iso.org.
Table 12-2. ISO 3166-1 Country CodesCountry code | Country name |
---|
AF | Afghanistan | AU | Australia | EG | Egypt | LV | Latvia | ES | Spain | US | United States |
Staying Put
Filling out the Address tab of the Active Directory Users And Computers user address properties entails modifying a lot of fields. To do this, you use the Put command, as shown in the following code:
objUser.Put "streetAddress", "123 main st"
objUser.Put "postOfficeBox", "po box 12"
objUser.Put "l", "Bedrock"
objUser.Put "st", "Arkansas"
objUser.Put "postalCode" , "12345"
objUser.Put "c", "US"
objUser.Put "co", "United States"
objUser.Put "countryCode", "840"
Most of the fields are self-explanatory. The only two that do not make much sense are the small letter l for city and the country code, because of the way you fill it in, which you learned about earlier.
Warning  | The three country fields are not linked in Active Directory. You could easily have a c code value of US, a co code value of Zimbabwe, and a countryCode value of 470 (Malta). This could occur if someone uses Active Directory Users And Computers to make a change to the country property. When ADUC is used, it updates all three fields. If someone later runs a script to only update the countryCode value, or the co code value, then Active Directory Users And Computers will still reflect the "translated value" of the c code. This could create havoc if your Enterprise Resource Planning (ERP) application uses the co or countryCode value, and not the c attribute. Best practice is to update all three fields via your script. Unfortunately, you're not always presented with an error; the script just does not seem to update, so you are left (or at least I am left) clicking the Refresh button in Active Directory Users And Computers as you wait for a replication event that never seems to take place. |
Note  | Do not forget to use the SetInfo method to commit your changes to Active Directory. If I seem to harp on this, it's because I've forgotten to do so on occasion, and I want to spare you the mental agony. This is one occasion when it is easy to commit. You just use this code: objUser.SetInfo. |
Output Information
After creating all those lovely updates, I want to see something to let me know the script has completed running. Obviously, if you were running this in the scheduler, you wouldn't want to present a message box (although you might want to write something to the event log). In your script, you use a simple WScript.Echo box to let you know the script completed. The script evaluates the Err object to catch any errors. Note: In this case, we must have On Error Resume Next turned on (that is, not commented out) or a runtime error will cause the script to fail before it gets to the Output section of the script. If an error were to occur, we would want to see the actual error number (Err.Number). The output code follows:
If Err.Number = 0 Then
WScript.Echo("User " & strOUName & " was modified")
Else
WScript.Echo "An error occurred. it was: " & Err.Number
End If
 |
Q. | To set the country name on the Address tab for Active Directory Users And Computers, what is required?
| A. | To update the country name on the Address tab for Active Directory Users And Computers, you must specify the c field and feed it a two-letter code that is found in ISO publication 3166. | Q. | What field name in ADSI is used to specify the city information?
| A. | You set the city information by assigning a value to the l (lowercase L) field after making the appropriate connection to Active Directory. | Q. | If you put an inappropriate letter code in the c field, what error message is displayed?
| A. | No error message is displayed. The update simply fails to display in ADUC. If, however, you go into ADSI Edit, you will see the value stored there. The Active Directory Users And Computers tool is smart enough to not display codes it does not understand. |
|
|
Modifying the user profile settings
1. | Open Microsoft Notepad or some other script editor.
| 2. | Open the \My Documents\Microsoft Press\VBScriptSBS\ch12\ModifyUserAddressTab.vbs script and save it as YourNameModifyUserProfile.vbs.
| 3. | Delete all but four of the Put statements in the Worker section. Once deleted, the Put statements will look like the following:
objUser.Put "streetAddress", "123 main st"
objUser.Put "postOfficeBox", "po box 12"
objUser.Put "l", "Bedrock"
objUser.Put "st", "Arkansas"
| 4. | We are going to assign values for the following four attributes: profilePath, scriptPath, homeDirectory, and homeDrive. Replace the "old" attributes with the user profile attributes and assign appropriate values to the attributes. Use folders and scripts accessible on your network, or you can use my values that are listed below:
Set objUser = GetObject(strProvider & strOUName & strOU & strDomain)
WScript.Echo strProvider & strOUName & strOU & strDomain 'debug info
objUser.put "profilePath", "\\London\profiles\myNewUser"
objUser.put "scriptPath", "logon.vbs"
objUser.Put "homeDirectory", "\\london\users\myNewUser"
objUser.Put "homeDrive", "H:"
objUser.SetInfo
| 5. | Save and run the script. You should see the Profile tab filled out, as seen in Figure 12-4. If your script generates errors, compare it with the \My Documents\Microsoft Press\VBScriptSBS\ch12\ModifyUserProfile.vbs script.
|
Modifying the user telephone settings
1. | Open Notepad or your favorite script editor.
| 2. | Open the \My Documents\Microsoft Press\VBScriptSBS\ch12\ModifyUser AddressTab.vbs script and save it as YourNameModifyTelephoneAttributes.vbs.
| 3. | Delete two of the Put statements in the Worker section of the script. After this deletion, the Put statements will look like the following:
objUser.Put "streetAddress", "123 main st"
objUser.Put "postOfficeBox", "po box 12"
objUser.Put "l", "Bedrock"
objUser.Put "st", "Arkansas"
objUser.Put "postalCode" , "12345"
objUser.Put "c", "US"
| 4. | We are going to assign values for the six attributes used to configure the Telephone tab in the User object in Active Directory. These attributes are: homePhone, pager, mobile, facsimileTelephoneNumber, ipPhone, and info. Replace the existing attributes from the Address tab information with the attributes from the Telephone tab. Assign appropriate values to each attribute, as seen in the completed Worker section below:
Set objUser = GetObject(strProvider & strOUName & strOU & strDomain)
WScript.Echo strProvider & strOUName & strOU & strDomain ' debug info
objUser.put "homePhone", "(215)788-4312"
objUser.put "pager", "(215)788-0112"
objUser.Put "mobile", "(715)654-2341"
objUser.Put "facsimileTelephoneNumber", "(215)788-3456"
objUser.Put "ipPhone", "192.168.6.112"
objUser.Put "info", "All contact information is confidential, " &_
"and is for official use only."
objUser.SetInfo
| 5. | Save and run your script. You should see the Telephone tab filled out, as seen in Figure 12-5. If not, compare your script with the \My Documents\Microsoft Press \VBScriptSBS\ch12\ModifyTelephoneAttributes.vbs script.
|
Creating multiple users
1. | Open Notepad or your favorite script editor.
| 2. | Open the \My Documents\Microsoft Press\VBScriptSBS\ch12\CreateUser.vbs script and save it as YourNameCreateThreeUsers.vbs.
| 3. | Declare two new variables in the Header section: strUsers (which will contain a string of three user names) and aryUsers (which will be an array of user names) aryUsers will become an array once the Split function is used on strUsers. The two new variable declaration statements are seen below:
Dim strUsers 'a string of three users here
Dim aryUsers 'an array of users from SPLIT
| 4. | In the Reference section, assign three user names to the strUsers variable: myBoss, myDirect1, and myDirect2. This is seen in the following code:
strUsers = "cn=MyBoss,cn=MyDirect1,cn=MyDirect2"
| 5. | Assign aryUsers to hold the array that is created by using the Split function on the "strUsers" string when we break the string at the comma character. This is seen below:
aryUsers = Split(strUsers,",")
| 6. | Instead of hardcoding the value of strOUname, we will assign values to it by using For Each...Next to walk through the array. Place this code directly under strClass = "User". This is seen below.
For Each strOUname In aryUsers
| 7. | Delete the strOUname= "cn=MyNewUser" line.
| 8. | Add the Next statement after you call objOU.SetInfo.
| 9. | Just above the Next statement and immediately following objOU.SetInfo, call the subError subroutine. The placement is seen here:
objOU.SetInfo
subError
Next
| 10. | Turn the error handler into a subroutine called subError. To do this, use the Sub statement followed by the name subError. End your subroutine with the End Sub statement. This is seen here:
Sub subError
If Err.number = 0 Then
WScript.Echo(strOUname & " was created")
Else If Err.number = "-2147019886" Then
WScript.Echo strOUname & " already exists"
Else
WScript.Echo " error on the play " & Err.Number
End If
End If
End sub
| 11. | Save and run your script. You should see three new users created in the Mred OU. If they are not, compare your script with CreateThreeUsers.vbs.
|
Modifying the organizational settings
1. | Open Notepad or your favorite script editor.
| 2. | Open the \My Documents\Microsoft Press\VBScriptSBS\ch12\ModifyUserAddressTab.vbs script and save it as YourNameModifyOrganizationPage.vbs.
| 3. | Delete all but four of the Put statements in the Worker section of the script. After this deletion, the Put statements will look like the following:
objUser.Put "streetAddress", "123 main st"
objUser.Put "postOfficeBox", "po box 12"
objUser.Put "l", "Bedrock"
objUser.Put "st", "Arkansas"
| 4. | We are going to assign values to the four attributes used to configure the Organization tab of the User object in Active Directory. These attributes are: title, department, company, and str Manager. Replace the existing attributes from the Address tab information with the attributes from the Worker section, as seen below:
Set objUser = GetObject(strProvider & strOUName & strOU & strDomain)
WScript.Echo strProvider & strOUName & strOU & strDomain 'debug info
objUser.Put "title", "Mid-Level Manager"
objUser.Put "department", "Sales"
objUser.Put "company", "North Wind Traders"
objUser.Put "manager", strManager & strOU & strdomain
objUser.SetInfo
| 5. | In the Reference section of your script, assign a value for the strManager variable. MyNewUser's boss is named MyBoss and was created when we created the three users in the previous exercise.
strManager = "cn=MyBoss,"
| 6. | Save and run your script. The Organization tab should be filled out and look like Figure 12-6. If it does not, then compare your script with the \My Documents\Microsoft Press\VBScriptSBS\ch12\ModifyOrganizationalPage.vbs script.
|
Modifying Terminal Server Settings
One of the big problems users of Microsoft Terminal Services faced in the Windows 2000 days was the inability to modify Terminal Server profile information via a script. This was particularly frustrating because the information appeared on a tab in Active Directory Users And Computerscausing many administrators to assume the information was "in Active Directory" and that it should be accessible through ADSI scripting. In Windows Server 2003, a new interface was introduced that enables ADSI scripting to edit Terminal Server settings. This interface is called the IADsTSUserEx, and it exposes the properties listed in Table 12-3.
Table 12-3. Terminal Server Setting PropertiesProperty | Meaning | Value |
---|
TerminalServicesProfilePath | Roaming or mandatory profile path to use when the user logs on to the Terminal Server | Disabled = 0,
Enabled = 1 | TerminalServicesHomeDirectory | Home directory for the user | UNC path to directory | TerminalServicesHomeDrive | Home drive for the user | Drive letter followed by colon | AllowLogon | Value that specifies whether the user is allowed to log on to the Terminal Server | Disabled = 0,
Enabled = 1 | EnableRemoteControl | Value that specifies whether to allow remote observation or remote control of the user's Terminal Services session | Disable = 0,
EnableInputNotify = 1,
EnableInputNoNotify = 2,
EnableNoInputNotify = 3,
EnableNoInputNoNotify = 4 | MaxDisconnectionTime | Maximum amount of time a disconnected session remains viable | Time in minutes | MaxConnectionTime | Maximum duration of a connection | Time in minutes | MaxIdleTime | Maximum amount of time a session can remain idle | Time in minutes | ReconnectionAction | Value that specifies whether to allow reconnection to a disconnected Terminal Services session from any client computer | Any Client = 0,
Originating client = 1 | BrokenConnectionAction | Value that specifies the action to take when a Terminal Services session limit is reached | Disconnect = 0,
End Session = 1 | ConnectClientDrivesAtLogon | Value that specifies whether to reconnect to mapped client drives at logon | Disabled = 0, Enabled = 1 | ConnectClientPrintersAtLogon | Value that specifies whether to reconnect to mapped client printers at logon | Disabled = 0, Enabled = 1 | DefaultToMainPrinter | Value that specifies whether to print automatically to the client's default printer | Disabled = 0, Enabled = 1 | TerminalServicesWorkDirectory | Working directory path for the user | UNC path to directory | TerminalServicesInitialProgram | Path and file name of the application that the user wants to start automatically when the user logs on to the Terminal Server | UNC path to directory |
The following script, ModifyTerminalServerProperties.vbs, will assign values to all of the available properties for a user Terminal Server profile. Please keep in mind, this script requires access to a Windows Server 2003 machine, and you will need to give the script the appropriate name for both the User object and the server itself. Also remember that under normal circumstances, one would not need to assign values to all of these properties, because many of them can be set server side, instead of user side. One reason, however, for assigning values on the user side of the equation is that under certain circumstances, a network administrator wants to allow the user settings to override the "default" server settings.
In the ModifyTerminalServerProperties.vbs script, all of the property values have been abstracted into constants that are assigned values in the Reference section of the script. This was done to facilitate modifying the script in the future, as well as to provide a better place for script documentation. In the version of this script in the \My Documents\Microsoft Press\VBScriptSBS\CD-ROM\ch12 folder, the script is fully commented (most comments in the script below have been removed for clarity).
ModifyTerminalServerProperties.vbs
Option Explicit
On Error Resume Next
Dim strProvider 'defines how will talk
Dim strOU 'path to where object is located
Dim strDomain 'name of domain connecting to
Dim strOUName 'user name
Dim objUser 'holds connection to ADSI
strProvider = "LDAP://"
strOU = "ou=mred,"
strDomain = "dc=nwtraders,dc=msft"
strOUName = "cn=myNewUser,"
Const blnENABLED = 1
Const blnBROKEN_CONNECTION = 1
Const blnRECONNECTION = 1
Const intREMOTE_CONTROL = 1
Const intMAX_CONNECTION=60
Const intMAX_DISCONNECT=6
Const intMAX_IDLE=10
Const strHOME_DIR = "\\London\Shared\"
Const strHOME_DRIVE = "t:"
Const strPROFILE_PATH = "\\London\Profiles\"
Const strINIT_PROG = "notepad.exe"
Const strWORK_DIR = "\\London\Profiles\"
Const strTEMP_DIR = "\tmp"
Set objUser = GetObject(strProvider & strOUName & strOU & strDomain)
'Terminal Services Profile tab
objUser.AllowLogon = blnENABLED
objUser.TerminalServicesHomeDirectory = strHOME_DIR & funfix(strOUName)
objUser.TerminalServicesHomeDrive = strHOME_DRIVE
objUser.TerminalServicesProfilePath = strPROFILE_PATH & funfix(strOUname)
'Remote control tab. This property sets ALL 4 controls on the tab
objUser.EnableRemoteControl = intREMOTE_CONTROL
'Sessions tab
objUser.BrokenConnectionAction = blnBROKEN_CONNECTION
objUser.MaxConnectionTime = intMAX_CONNECTION
objUser.MaxDisconnectionTime = intMAX_DISCONNECT
objUser.MaxIdleTime = intMAX_IDLE
objUser.ReconnectionAction = blnRECONNECTION
'Environment tab
objUser.ConnectClientDrivesAtLogon = blnENABLED
objUser.ConnectClientPrintersAtLogon = blnENABLED
objUser.DefaultToMainPrinter = blnENABLED
objUser.TerminalServicesInitialProgram = strINIT_PROG
objUser.TerminalServicesWorkDirectory = strWORK_DIR & funfix(strOUname) & strTEMP_DIR
objUser.SetInfo
subError
'***************** Subs and Functions are below **************
Sub subError
If Err.Number = 0 Then
WScript.Echo("User " & funFix(strOUName) & " was modified")
Else
WScript.Echo "An error occurred. It was: " & Err.Number
End If
End sub
Function funfix (strin)
funFix = Mid(strin,4)
funfix = Mid(funFix,1,Len(funFix)-1)
End Function
Modifying the Terminal Server user profile settings
1. | Open Notepad or some other script editor.
| 2. | Open the \My Documents\Microsoft Press\VBScriptSBS\ch12\ModifyUserAddressTab.vbs script and save it as YourNameModifyTerminalServerProfile.vbs.
| 3. | In the Reference section of your script, under the strOUName= "CN=MyNewUser" line, add a constant blnENABLED and set it equal to one.
| 4. | On the next line, define a constant called strHOME_DIR and set it equal to "\\London\Shared\".
| 5. | On the next line, define a constant called strHOME_DRIVE and set it equal to "t:".
| 6. | On the next line, define a constant called strPROFILE_PATH and set it equal to "\\London\Profiles\".
| 7. | The completed Reference section will look like the following:
strProvider = "LDAP://"
strOU = "ou=mred,"
strDomain = "dc=nwtraders,dc=msft"
strOUName = "cn=myNewUser,"
Const blnENABLED = 1
Const strHOME_DIR = "\\London\Shared\"
Const strHOME_DRIVE = "t:"
Const strPROFILE_PATH = "\\London\Profiles\"
| 8. | Delete WScript.Echo and all the objUser commands except for the objUser.SetInfo command under the Set objUser line. Your revised Worker and Output section will now look like the following:
Set objUser = GetObject(strProvider & strOUName & strOU & strDomain)
objUser.SetInfo
If Err.Number = 0 Then
WScript.Echo("User " & strOUName & " was modified")
Else
WScript.Echo "An error occurred. it was: " & Err.Number
End If
| 9. | Turn on allow logon by assigning the blnENABLED value to objUser.AllowLogon, as seen below:
objUser.AllowLogon = blnENABLED
| 10. | Set the terminal server home directory by assigning the strHOME_DIR value to objUser.TerminalServicesHomeDirectory, as seen below. Use the funfix function to clean up the user name. (Note: We have not yet created the funfix function!)
objUser.TerminalServicesHomeDirectory = strHOME_DIR & funfix(strOUName)
| 11. | Set the terminal server home drive letter by assigning the strHOME_DRIVE constant to objUser.TerminalServicesHomeDrive, as seen below:
objUser.TerminalServicesHomeDrive = strHOME_DRIVE
| 12. | Set the profile path for the terminal server user by assigning the strPROFILE_PATH constant to objUser.TerminalServicesProfilePath. Use the funfix function to clean up the username.
objUser.TerminalServicesProfilePath = strPROFILE_PATH & funfix(strOUname)
| 13. | Turn the If Err.Number section of code into a subroutine. Do this by adding S ub s ubError above the section of code, and E nd sub at the bottom of the code. It will look like the following when completed.
Sub subError
If Err.Number = 0 Then
WScript.Echo("User " & funFix(strOUName) & " was modified")
Else
WScript.Echo "An error occurred. It was: " & Err.Number
End If
End sub
| 14. | On the line following objUser.SetInfo call the subError subroutine. This is seen in the code below:
| 15. | Copy the funfix function from the \My Documents\Microsoft Press\VBScriptSBS\Utilities\Funfix.vbs script to the bottom of your script. The funfix function looks like the following:
Function funfix (strin)
funFix = Mid(strin,4) 'removes cn= from strOUName to give username
funfix = Mid(funFix,1,Len(funFix)-1) 'removes "," from end of strOUName
End Function
| 16. | Save and run your script. If there are problems, compare it with the ModifyTerminalServerProfile.vbs script in the Chapter 12 folder.
|
|