Windows Tips &amp Tricks UPDATE, October 4, 2004, —brought to you by the Windows IT Pro Network and the FAQ for Windows site


Q. How can I create a summary of the contents of the organizational units (OUs) in my environment?

A. I recently needed to quickly document a client's OU structure for a domain and had to include in the documentation the number of users, groups, computers, and contacts in each OU. To achieve this, I wrote a short script--oulist.vbs--that uses Microsoft Active Directory Service Interfaces (ADSI) to interrogate Active Directory (AD) and produce a report that details the specified container's content. To use oulist.vbs, you can either save the following code into a file (name it oulist.vbs) or download the script.

Option Explicit                              Dim strLdapPath, objConnection, objChild, dtmCreate                              Dim totalUsers, totalComputers, totalGroups, totalContacts                              totalUsers=0                              totalGroups=0                              totalComputers=0                              totalContacts=0                              ' Check that all required arguments have been passed.                              If Wscript.Arguments.Count                               

Oulist.vbs calls the GetDetail function to check the content of the passed container. The script then checks for OUs in the current container and, for each OU it finds, calls the function again. A process that calls itself is known as a recursive process. Running oulist.vbs produces output on screen that's similar to the following:

C:\scripts>cscript oulist.vbs dc=savilltech,dc=net                              Microsoft (R) Windows Script Host Version 5.6                              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.                               dc=savilltech,dc=net                               (0 users 0 groups 0 computers 0 contacts)                               - OU=Domain Controllers                                 (0 users 0 groups 1 computers 0 contacts)                               - OU=test                                 (0 users 0 groups 0 computers 0 contacts)                                 - OU=subtest1                                   (0 users 0 groups 0 computers 0 contacts)                                   - OU=subsubtest1                                     (0 users 0 groups 0 computers 0 contacts)                                   - OU=subsubtest2                                     (0 users 0 groups 0 computers 0 contacts)                                 - OU=subtest2                                   (0 users 0 groups 0 computers 0 contacts)                                   - OU=subsub2test1                                     (0 users 0 groups 2 computers 0 contacts)                                   - OU=subsub2test2                                     (1 users 1 groups 1 computers 1 contacts)                                     - OU=subsubsubtest                                       (0 users 0 groups 0 computers 0 contacts)                              Totals: 1 users 1 groups 4 computers 1 contacts                              Operation Completed

It's important to use the Cscript command; if you don't specify Cscript, every line of text in the output will pop up in a dialog box.

Q. How can I create an HTML view of my organizational unit (OU) structure?

A. To answer this, I modified the script in the FAQ "How can I create a summary of the contents of the organizational units (OUs) in my environment?" so that it outputs to a HTML file and includes the total number of OUs and the maximum depth of OUs that it found. Download the code and extract the oulisthtmlgraph.vbs file from (The zip file also contains oulisthtml.vbs, an earlier version of the script that doesn't output HTML graphics.) In addition, contains five image files, which you should place in a folder named "images" in the directory where your output HTML file will be stored. (Placing the image file in this location ensures that Microsoft Internet Explorer (IE) can find the graphics when it opens the HTML file.) The figure shows an example of the script's HTML output.

Q. What's conditional DNS forwarding?

A. Windows 2000 Server DNS can forward DNS resolution requests that a DNS server can't resolve locally. This forwarding occurs when the request is for a domain for which the DNS server isn't authoritative and the request isn't in the DNS server's cache waiting to be forwarded to another DNS server. The ability to forward DNS resolution requests is a global setting that applies to all unresolvable addresses.

Windows Server 2003 offers the ability to forward unresolvable requests to different DNS servers. Depending on the domain in which the request originated and whether the request matches multiple defined forwarding rules, the DNS server uses the IP address that corresponds to the forwarding rule that most closely matches the resolution request. For example, if a DNS server has forwarding configured as the table shows, the DNS server will forward a request for to, because that IP address is a closer match to than it is to

Conditional DNS forwarding is a useful feature that avoids the usual recursive nature of DNS resolution requests, in which DNS must first find DNS servers for .com, then, and so on. If you have a large namespace, you might consider using conditional DNS forwarding to speed up resolution requests. This feature is also useful for connecting two organizations, especially if one organization uses a nonstandard namespace--for example, savilltech.local--that the typical DNS name-resolution process would never find.

Q. How can I specify a forwarding condition for a DNS domain?

A. To specify conditional forwarding for a DNS domain, perform these steps:

  1. Log on as a domain administrator on each DNS server for which you want to add conditional forwarding.
  2. Start the Microsoft Management Console (MMC) DNS snap-in (Start, Programs, Administrative Tools, DNS).
  3. Right-click the DNS server and select Properties.
  4. Select the Forwarders tab.
  5. Click the New button in the DNS domain section.
  6. Enter the name of the DNS domain to which the forwarding will apply--for example, click OK.
  7. Enter the IP addresses of the DNS servers in the forwarded DNS domain by typing the addresses one at a time in the Add field and clicking Add. You should add multiple entries for the DNS servers that service the zone for which you're forwarding. After you finish entering addresses, click OK.

After you've enabled conditional DNS forwarding, you should test whether it's working by performing a DNS resolution request for hosts that are in the DNS domains for which you've configured conditional forwarding. For example, to perform a test, you can use the Nslookup command to query DNS for records that would be serviced in the forwarded DNS domain.

Q. I have Microsoft Exchange 2000 Server installed and want to run the Windows Server 2003 Adprep /Forestprep command. What must I do to avoid corrupting Active Directory (AD)?

A. When Exchange 2000 is installed, it modifies the AD schema. Three of these modifications are additions of the houseIdentifier, Secretary, and labeledURI attributes for the InetOrgPerson class. However, these Exchange 2000 attributes don't adhere to Internet Engineering Task Force (IETF) Request for Comments (RFC) 2798. When the Windows 2003 Adprep /Forestprep command runs, it redefines the attributes so that they conform to RFC 2798. This renaming causes Windows to rename the existing definitions for other attributes so that they're RFC-compliant and will cause future problems for your Exchange environment. (If you installed Exchange 2000 after running Windows 2003 forestprep, these problems won't occur.)

The Microsoft article "Windows Server 2003 adprep /forestprep Command Causes Mangled Attributes in Windows 2000 Forests That Contain Exchange 2000 Servers" describes solutions to a variety of problems related to Exchange 2000 schema changes and renamed attributes. Here, I discuss the procedure for changing the attribute names so that the Windows 2003 Adprep /Forestprep process doesn't mangle the attributes. This procedure addresses the most common scenario, in which Exchange 2000 is installed and you haven't yet run the Windows 2003 Adprep /Forestprep command. Before you perform the following steps, you need to enable schema modifications, which I discuss in the FAQ "How do I allow modifications to the schema?"

  1. Log on as a Schema Admin (the Administrator of the forest root domain has this role by default).
  2. Paste the following text into a file named Inetorgpersonprevent.ldf in the %systemroot%\IOP folder. You'll need to create the IOP folder. (You can copy and paste this text from the Microsoft article I mentioned earlier instead of typing it.)
    dn: CN=ms-Exch-Assistant-Name,CN=Schema,CN=Configuration,DC=X                              changetype: Modify                              replace: lDAPDisplayName                              lDAPDisplayName: msExchAssistantName                              -                              dn: CN=ms-Exch-LabeledURI,CN=Schema,CN=Configuration,DC=X                              changetype: Modify                              replace: lDAPDisplayName                              lDAPDisplayName: msExchLabeledURI                              -                              dn: CN=ms-Exch-House-Identifier,CN=Schema,CN=Configuration,DC=X                              changetype: Modify                              replace: lDAPDisplayName                              lDAPDisplayName: msExchHouseIdentifier                              -                              dn:                              changetype: Modify                              add: schemaUpdateNow                              schemaUpdateNow: 1                              -
  3. Start a command prompt (Start, Run, cmd.exe).
  4. Change the current folder to the IOP folder.
  5. Run the Ldifde command (the following line shows an example):
    ldifde -i -f inetorgpersonprevent.ldf -v -c DC=X "DC=SAVILLTECH,DC=COM"

The command should be on one line, and you need to replace DC=SAVILLTECH,DC=COM with the distinguished name (DN) of your forest. After you enter the command, messages similar to the following are displayed on screen:

Connecting to ""                              Logging in as current user using SSPI                              Importing directory from file "inetorgpersonprevent.ldf"                              Loading entries                              1: CN=ms-Exch-Assistant-Name,CN=Schema,CN=Configuration,DC=SAVILLTECH,DC                              =COM                              Entry modified successfully.                              2: CN=ms-Exch-LabeledURI,CN=Schema,CN=Configuration,DC=SAVILLTECH,DC=COM                              Entry modified successfully.                              3: CN=ms-Exch-House-Identifier,CN=Schema,CN=Configuration,DC=SAVILLTECH,                              DC=COM                              Entry modified successfully.                              4: (null)                              Entry modified successfully.                              4 entries modified successfully.                              The command has completed successfully.

You could use the ADSIEdit tool (adsiedit.msc) to check whether the attribute renaming worked--for example, the lDAPDisplayName attribute of the ms-Exch-LabeledURI class should now be renamed msExchLabeledURI instead of LabeledURI. If necessary, you can disable the schema changes that you enabled to perform this procedure.