I'm trying to use the CrUM.wsf script that you introduced in "Script User Account and Mailbox Creation," September 2002, InstantDoc ID 25843 to create user accounts and Exchange Server mailboxes in an organizational unit (OU) in the domain root. I'm using the method you explained in "Making a Single-Task Command-Line Application or Script Perform Repetitive Tasks," July 2005, InstantDoc ID 46501 to turn CrUM.wsf into a tool that lets you create multiple user accounts and mailboxes, but I'm having no luck. The script keeps generating the following error: 438 = Object doesn't support this property or method. The script cannot continue until this error is resolved. When I try to create the users in a valid child OU, the script tells me OU not found. I'm quite desperate. Can you help me?
The resolution to this reader's problem required several email exchanges between the reader and myself. Even if automating the creation of user accounts and mailboxes isn't a priority for you, you might find useful the approach we used to troubleshoot the script.
I first asked the reader to remark the On Error Resume Next statement in the CrUM.wsf script, then rerun the script. This step is essential for resolving most script errors. Removing the statement causes the script to abort when it encounters an error, thus providing information—primarily, the line number at which the script is failing—that you won't find in the VBScript Err object's properties. In fact, most scripts can be improved by using the Err object only when you're implementing your own error handling, and even then, I recommend using On Error GoTo 0 (rather than On Error Resume Next) to cause the script to fail when it encounters an unhandled error. Although you can use the Err.Raise method to create your own error and hard-code a line number to display in an error message, any changes you make to the code will require you to update the hard-coded line number.
A better method exists for resolving script errors. Rather than returning an error to the command line or to a Windows Script Host (WSH) dialog box, run the script with any required parameters and the //x cscript or wscript parameter (to run a script debugger such as Microsoft Script Editor), then walk through the code by pressing F11 and evaluating the content that appears in the Locals window.
When the reader ran the script after remarking the On Error Resume Next statement, he discovered that the script was failing at line 87. That line happened to be the first line of the CreateMailbox method, which Listing 1 shows. (The method wraps across multiple lines, but runtime script errors report only the first line of wrapped lines of code.) The reader then ran the code directly on the Exchange server and discovered that the script ran fine. He correctly assumed from this experiment that the CreateMailbox method required something that existed on the Exchange server but not on his client.
I explained to the reader that the Exchange client tools (which contain the Exchange Management Components) are essential to running CrUM.wsf, which relies on Collaboration Data Objects for Exchange Management (CDOEXM). The CDOEXM DLL (cdoexm.dll) is installed by default on Exchange Server 2003 and Exchange 2000 Server systems. If you run the script on a client computer or non-Exchange server, you must either install the Exchange client tools or copy and register cdoexm.dll on that system.
The reader took care of the missing DLL. However, the script still returned the error message that Figure 1 shows. The error was occurring at the following line:
Set objOU = GetObject _(sContainerPath(strOU))
This code binds to the OU in which the user account will be created. The GetObject function, the IADsContainer Active Directory Service Interfaces (ADSI), and two functions I created—sContainerPath and sADsPath—complete this task. (For more details about these functions, see "Script User Account and Mailbox Creation.")
The error message suggested that the provided OU was invalid. The reader told me he was using the following /OU: parameter:
The /OU: parameter specifies where you want to create the user account. This parameter uses the standard distinguished name (DN) ordering format, which starts from the leaf container in which the account should be created and moves up the hierarchy to the parent container.
Note that the OU= naming attribute appears only after the reader specifies the User Accounts container value. This isn't a user error: CrUM.wsf automatically adds the first naming attribute. Although the absence of the first naming attribute wasn't the reason that the script was failing, I probably shouldn't have written the script to add the first naming attribute. Adding the OU= naming attribute before specifying the first OU is a more consistent approach. You can modify CrUM.wsf so that it doesn't add the initial naming attribute, then you can write out the value of the switch:
However, the Manager OU was actually the leaf container in the reader's environment, so the correct ordering for the parameter was:
When the reader reordered this parameter, the script completed successfully. Note that when you're debugging an error such as this one, you can first reduce the leaf structure (e.g., to Manager only). If the code works at that level, you know that the problem lies in your declaration of the OU (as opposed to an access-permission problem).