Active Directory Service Interfaces

One of the most common questions I'm asked about Microsoft Active Directory Service Interfaces (ADSI) is, "How can you programmatically manipulate profile paths for Windows NT Server 4.0, Terminal Server Edition (WTS)?" Unfortunately, you can't use ADSI to directly manipulate the WTS profile-path attributes because the NT SAM stores these attributes in the User Parameters field, which ADSI can't access. Oddly, the ADSI resource kit includes a DLL for managing RAS permissions, which also reside in the User Parameters field, but doesn't include a DLL for manipulating WTS permissions.

To manipulate the WTS profile-path attributes, you can use WTSAPI32. To make WTSAPI32 easier to work with, you can create a COM object that wraps the native WTSAPI32 functions. You can then use the WTS COM object to manipulate the Terminal Server Profile Path, Terminal Server Home Directory, and Terminal Server Home Directory Drive Mapping attributes. This object lets you use the WTSAPI32 functions with the same ease you've come to expect from ADSI.

Although COM object development deviates a bit from the topics I typically discuss in this column, the WTSAPI32 functions are valuable to systems administrators who need to programmatically manipulate the profile-path, home-directory, and home-directory-drive attributes in a WTS, Windows 2000 Server Terminal Services, Citrix WinFrame, or Citrix MetaFrame environment. In addition, this minor deviation provides the perfect opportunity to delve into the creation of COM objects in Microsoft Visual Basic (VB)—an essential step for taking scripting to a whole new level of usability.

Why Use COM Objects?
A COM object is a kind of black box. Input goes into the object. The object automatically performs its job with no interaction from users. The object returns output if needed.

Because COM objects don't require user interaction, you might already be using COM objects without realizing it. Every time you instantiate the FileSystemObject object or use ADSI to bind to an object, you're using a COM object. Using a custom COM object affords you all the same benefits you've come to enjoy with using ADSI, FileSystemObject, and other out-of-the-box scripting objects. In addition, COM objects offer these advantages:

  • After you instantiate COM objects, they offer better performance than equivalent Windows Script Host (WSH) and VBScript functions in scripts because COM objects are precompiled.
  • COM objects let you reuse code across multiple automation languages, such as VBScript, JScript, JavaScript, and Perl.
  • COM objects let you reuse code throughout an organization. You can even create a component repository to prevent duplication of development efforts.
  • COM objects facilitate multi-tier application development so that you can separate business logic from application logic.
  • COM objects facilitate easier code testing. You need to develop and test a COM object only once.

Despite these advantages, many systems administrators shudder at the thought of developing COM objects. Perhaps their perception of COM object development stems from C++ developers' stories about COM's supposed complexity. Contrary to popular opinion, creating COM objects in VB is easy, and they work properly on the VB platform without any extraordinary intervention.

Using VB, you can wrap your most commonly performed complex tasks (such as creating a new user account, home directory, and share) with a public function that a COM object exposes. Wrapping tasks ensures that those tasks are performed the same way every time. If you use a certain VBScript function often, you can even use VB to create a COM object that incorporates that function.

The Golden Rules
Before you can create a COM object in VB, you must know about two important rules. First, you must use the enterprise or professional edition of VB to compile COM objects. You can't use the learning edition or the version that comes with Microsoft Office. Second, you can't incorporate any GUI elements, such as message boxes or forms. So, for example, you can't use MsgBox or Debug.Print statements or the values they return.

Next Time
Next month, I'll show you how to create the WTS COM object, which will contain the functions to manipulate the Terminal Server Profile Path, Terminal Server Home Directory, and Terminal Server Home Directory Drive Mapping attributes. You'll be able to use this object in any scripting language that supports automation.