Accessing the Active Directory
and IISAdmin objects

by Rick Strahl, West Wind Technologies
http://www.west-wind.com/

last updated: March 17, 1998

Download IISAdmin component and Metabase Property Manager

Microsoft has recently released the first version of Active Directory which is a system wide mechanism for accessing network objects, directories, paths, as well as hardware and software components installed on machines both on the local and remote machines.

One of the most prominent implementations of an ADS Service provider is the System Admin Console that was released with the NT 4.0 Option pack (NT Enterprise). Both Internet Information Server and Transaction Server can be adminstered programmatically through this interface. I haven't looked at the MTS interface so the following discussion will center on IIS 4.0.

Active Directory has a built in programmatic Automation interface that allows accessing ADS providers via an Automation interface. Unfortunately this Automation interface is not currently accessible directly from VFP due to some incompatibilities.

How do the IISAdmin Objects work

IIS 4.0 has introduced a new management interface that's hosted inside the Microsoft Management Console as a 'Snap In' provider. As a snap-in IIS Admin provides a common inteface consisting of a treeview (Collections programmatically) and Property Sheets (properties or further property collections). Previous versions of IIS saved all of its configuration data in the registry, but with IIS 4.0 Microsoft introduced yet another new storage mechanism called the Metabase, which is a proprietary binary format that supposedly provides speedier access to the data and hierarchical storage that matches more closely to the object model that ADS presents.

The Active Directory Administration objects and therefore the IIS Admin objects are implemented a COM object. Essentially the Management console is a custom front end to metabase data that is retrieved via this COM interface. Unfortunately the GUI interface does not expose all of the properties, and Microsoft was not considerate enough to provide a source browser/editor for the Metabase yet (one is promised in the next Resource Kit for NT Server). So, currently we're stuck with reading and writing some values programmatically.

Even more unfortunate is the fact that although ADS is a COM object there's no easy way to access the directory mapping mechanism to VFP. The following works in Visual Basic, but does not map to VFP:

Set oIIsPath = GetObject("IIS://LOCALHOST/W3SVC/1/ROOT")

This single line of code 'sets the path' to an Active Directory container object - in this case the Web Root of an IIS 4.0 Web server. Notice that each path along the way (LOCALHOST - W3SVC etc) are each containers that you can also access. The result is another object which has specific properties or collections that you can explicitly retrieve. Containers can also have methods. For example, the W3SVC (IISWebServer object) has Start and Stop methods to start and stop the Web Service.

Once you have an object reference (like oIISPath above) you can now retrieve and set properties like this:

llBasicAuthentication = oIISPath.AuthBasic
lcDefaultDocument = oIISPath.DefaultDoc
oIISPath.DefaultDoc="Default.wc,Default.htm,Default.asp"
llBasicAuthentication = oIISPath.Get("AuthBasic")
lcDefaultDocument = oIISPath.Get("DefaultDoc")
oIISPath.Set("DefaultDoc","Default.wc,Default.htm,Default.asp")
llBasicAuthentication = oIISPath.AuthBasic
lcDefaultDocument = oIISPath.DefaultDoc

Notice that you can access properties directly or via object methods to Get and Set. Now why would you use the latter? Simple - it allows for dynamic runtime setting of these values based on user input or dynamic conditions rather than forcing a fixed property name, which is very useful indeed.

Cool - you can do it in VB but unfortunately the GetObject() does not work in Visual FoxPro. While you can explicitly create an ADS object or the IISAdmin object, I have been unable to figure out how to set the path as in the VB GetObject call.

Making it work in Visual FoxPro

So, in order to work around this problem I created a small VB5 component that encapsulates the basic IISAdmin interface and also provides some basic functionality such as creating virtual directory entries and script maps which was required for my Web Connection install program. With the component registered (start a DOS prompt and then run: REGSVR32 wwIISAdmin.dll) you can do the following in Visual FoxPro:

loIIS=CREATE("wwIISAdmin.IIS4Config")
IF loIIS.ConnectPath("IIS://LOCALHOST/W3SVC/1/ROOT")
   ? loIIS.GetValue("AuthBasicIsolated")
   ? loIIS.GetValue("DefaultDoc")

   ? loIIS.m_oIISObj.Stop()
   * ? loIIS.m_oIISObj.Start()
ELSE
wait window "Unable to retrieve path..."
ENDIF
In addition you can use the following methods:
IF loIIS.CreateVirtual("MyVirtualPath","c:\westwind\MyVirtual")
   loIIS.SetValue("AppIsolated",.T.)  && Set as separate Memory Space
   loIIS.SetValue("AuthBasic",.F.)   && Don't allow basic auth
   loIIS.SetValue("AuthNTLM",.T.)  && Only NT Challenge Response
ENDIF

SetValue() and GetValue() are wrappers around the actual property retrieval values and provide for error handling. But ADS also provides enumeration methods and support for stringlists which will not work with Set and GetValue() at this time. However, wwIISAdmin also exposes the actual underlying container object with the m_oIISObj property, which you can use directly to access native ADS functionality without the wrapper functions:

IF loIIS.ConnectPath("IIS://LOCALHOST/W3SVC/1")
   loIISPath = loIIS.m_oIISObj
   loIISPath.AppIsolated = .T.
   loIISPath.AuthBasic=.T.
   laScriptMaps=loIISPath.GetEx("ScriptMaps")  && Special String List Object
   ... modify laScriptMaps
   loIISPath.PutEx("ScriptMaps",lascriptMaps)
ENDIF

If you use this direct approach you need to make sure you have error handling in place as accessing an invalid property or setting an invalid value will raise an OLE Exception in the COM object. If you use the component Get and Setvalue() methods no error is raised and the return value will be NULL instead or SetValue() will return .F.

It's important to note that this component and everything that was described above should work with any ADS provider. I'm using IIS here, because of my initial need to configure IIS programmatically for my Web Connection install program. But in the future you'll be able to use Active Directory to connect and configure drive and directory options, device information, just about anything in Control Panel, Performance Monitor etc. Active Directory and the Admin objects are the mechanism that will allow NT to be programmatically accessible. So, while the focus here has been limited to IIS, look at it as a first glimpse of what's to come with Active Directory in NT.

The component also provides a visual interface to allow you to interactively view and set properties for any ActiveDirectory path. For detailed property and method reference on the Active Directory and IISAdmin objects check on MSDN and search for ActiveDirectory, ADSI Object and IISAdmin Object.

Installation

To install the Admin component and GUI property utility you can download it from http://www.west-wind.com/files/iis4admin.zip. Unzip the file and run:

RegSvr32 iisadmin.dll

in the unzip directory to register the component. Once registered you can access the interactive utility by running the wwIISAdmin.exe file or by instantiating the component as described above.

wwIISAdmin Methods and Properties

Method Function
ConnectPath(cPath) Allows connection to a specified ADS path/container object. For IIS this typically means the server or a virtual directory or root. Example:
IIS://LOCALHOST/W3SVC/1/ROOT/VirtualDir
Returns:True or False.
GetValue(cProperty) Retrieves a value from a selected container object. All error handling is built in.
Returns: Requested value or NULL
SetValue(cProperty,vValue) Sets a property's value. Returns True or False.
CreateVirtual(cVirtual, cPhysical, lExecute) Creates an IIS virtual directory off the specified path. Specify the Virtual Directory and a physical DOS path and optionally (True) whether you want Execute rights on the virtual path. To delete a virtual path pass a Null string ("").
Returns: True or False.
CreateScriptMap(cScriptMap,cDLLPath) Creates a script map for a server or virtual path. Pass a script map mapping (.WC for example) and a full path to the mapped DLL.
Returns: True or False
PropertyForm() Displays a simple dialog that allows retrieving and setting of properties visually.
Property Function
m_oIISObj Object Reference to the currently selected container object. ConnectPath() and CreateVirtual() both set this object property so you can access any ADS methods applying to the container directly.