When Windows 2000 Active Directory (AD) first came out, it revolutionized the world of directory services. However, there were few command-line tools to manage AD. Fortunately, since the release of Windows Server 2003, Microsoft and third-party resources have developed new tools and updated existing tools that improve the manageability of AD. Five tools--AdFind, AdMod, OldCmp, Dsrevoke, and AdRestore--are considered must-haves by command-line aficionados. These tools are beefed up and ready for action in your AD environment.

Even if you prefer a GUI to a command-line interface, it's important to understand the capabilities of these five command-line tools. In many cases, there are no GUI alternatives to accomplish the tasks that these tools perform. Another great benefit of being versant with these tools is that you can use basic batch files to direct their efforts. Wouldn't you like these tools to automatically perform their duties while you take care of other business? You can make it happen with command-line tools. For example, you can use a simple two-line batch script that prompts OldCmp to automatically clean up inactive computer accounts and email you the results.

Let me show you how to use AdFind, AdMod, OldCmp, Dsrevoke, and AdRestore in your AD environment so that you can become more efficient in your daily work. All five tools are free. And, unless I point out otherwise, they all work in both Win2K and Windows 2003 domains.

AdFind has been out for a while but has recently been beefed up with some helpful features. AdFind is simply the best command-line tool available for querying AD--it's kind of like Windows 2003's Dsquery command on steroids.

Joe Richards, an AD expert who happens to know a bit about programming, developed AdFind. He has also written a slew of other cool utilities (aka Joeware), including AdMod and OldCmp. You'll find AdFind, AdMod, and OldCmp on his Web site at After you enter the site, click the Free Win32 C++ Based Tools link.

AdFind has numerous options--too many to cover here. So, I'll cover only the commonly used options. To get a complete list of options, simply run the command

adfind /?

One popular option is the -b option, which you can use to specify the base distinguished name (DN) from which to start a search. If you use this option by itself, AdFind displays the attributes of the object represented by the base DN plus the attributes of any objects contained under the base DN.

AdFind supports all the standard Lightweight Directory Access Protocol (LDAP) query options you might expect. You can use the -f option to specify a Request for Comments (RFC) 2254-compliant LDAP filter and the -s option to specify the scope of the search. To display certain attributes for an object, you can specify those attributes in a space-separated list at the end of the command. (By default, AdFind displays all attributes that have values.)

For example, suppose that in the Workstations organizational unit (OU), you want to find computer objects whose name begins with rallen. For each computer object found, you want AdFind to display the values of the name and whenCreated attributes. You'd use the command

adfind -b "ou=workstations,
dc=rallencorp,dc=com" -f "(&(objectcategory=computer)
name whenCreated

(Although this command appears on several lines here, you would enter it on one line in the command-shell window. The same holds true for the other multiline commands in this article.) Figure 1 shows sample results from this command.

You can use the -h option to target specific domain controllers (DCs) and the -gc option to query the Global Catalog (GC). If you need to authenticate with credentials other than the credentials with which you logged on, you use the -u and -up options to specify the username and password, respectively. If you want the base DN to be the default naming context of the root domain, the default naming context of the default domain, the configuration naming context, or the schema naming context, you can use the -root, -default, -config, or -schema options, respectively. If you use one of these options, you don't need to use the -b option. For example, the following command queries the GC under the forest root domain tree for all groups whose name starts with HR:

adfind -gc -root
  -f "(&(objectcategory=group)
  (name=HR*))" name

The features I've covered so far are standard in just about any LDAP query tool. But AdFind doesn't stop there. Here are some additional features AdFind offers:

  • You can sort or reverse sort the output based on the value of an attribute with the -sort and -rsort options, respectively.
  • You can display deleted objects with the -showdel option.
  • You can display how long a query takes to complete with the -elapsed option.
  • You can decode Large Integer, time-based attribute values with the -tdc option.

One of my favorite features of AdFind is its ability to display a query's Search Stats output. Search Stats is an LDAP control that returns various performance statistics about the query. For example, the following command displays the Search Stats information about my previous HR query, except this time I'm querying the GC under the default domain:

adfind -stats+only -default -gc
  -f "(&(objectcategory=group)
  (name=HR*))" name

Figure 2 shows the sample Search Stats output from this command. This information can be extremely useful when you need to debug a particular query or determine how efficient it is. The Search Stats output will include the hit rate of the query (i.e., the number of objects found versus the number of objects looked at), the indexes used, and the expanded query filter. Search Stats returns query information only for Windows 2003 domains.

A recent addition to the Joeware family is AdMod. Previously, I compared AdFind to Dsquery on steroids. A similar analogy can be made between AdMod and Microsoft's Dsmod, Dsmove, and Dsrm command-line tools. Although these Microsoft tools are helpful, they have a couple of major annoyances. First, you can target only specific types of objects. For example, with Dsmod, you can modify only computer, contact, group, OU, server, user, quota, and partition objects. If you want to modify any other type of object, you're out of luck. Second, in an effort to reduce the amount of typing you have to do when using these tools, they have options such as -samid (queries or sets the samAccountName attribute) and -mgr (queries or sets the manager attribute). Although Microsoft had good intentions when it came up with these shortened option names, I don't like them because I have to mentally associate samid with samAccountName and mgr with manager. Thus, these option names might be confusing to newcomers.

AdMod doesn't have any of these limitations. With it, you can modify (the default action), move (-move option), rename (-rename option), delete (-del and -treedelete options), and undelete (-undel option) objects. The undelete functionality is available only in Windows 2003 domains.

Modifying operations takes a little getting used to, but once you do, it's amazingly easy. To modify a single object, you need to specify the base DN by using the -b option. At the end of the command, you need to include the attribute action, which follows the format


Attribute represents the name of the attribute you want to modify. Operation represents the action to take on that attribute. There are five possible actions:

  • You can add a value to a single-value attribute, in which case you specify the + character.
  • You can clear a single-value or multivalue attribute, in which case you include the - character.
  • You can add multiple values to a multivalue attribute, in which case you specify the ++ character.
  • You can remove one or more values from a multivalue attribute, in which case you include the -- character.
  • You can update the value of a single-value or multivalue attribute (the default), in which case you don't include any character.

Value(s) represents the string value or string values you want to update, add, or remove. For default and + operations, you specify only one value. For ++ and -- operations, you use a semicolon-separated list to specify multiple values. For - operations, you don't need to specify any values.

For example, the following command updates the scriptpath attribute to login.vbs for the rallen user account:

admod -b cn=rallen,cn=users,

Here's how to clear the scriptpath attribute's value for the same user:

admod -b cn=rallen,cn=users,

If you want to modify a bunch of objects at once, you can pipe the output from AdFind to AdMod. AdFind's -dsq option returns only the DN of matching objects and places each DN on a separate line--perfect piping material. AdMod can iterate over this list and modify each object. For example, here's a command that uses AdFind and AdMod to clear the scriptpath attribute's value for all users in the default domain:

adfind -default
  -f "(&(objectcategory=
  -dsq | admod -unsafe "scriptpath:-:"

One item you might have noticed in this command is the -unsafe option. AdMod has a safety mechanism built into it so that you don't accidentally modify more objects than you intended. By default, AdMod modifies only 10 objects in one pass. You can, however, specify the -safety option along with the number of objects to modify. If you don't want any limitations, you use the -unsafe option.

A standard problem most AD administrators run into at some point is cleaning up old (aka inactive) computer accounts. It's not uncommon for computer accounts to be created and never used or left hanging around in the directory after a computer has been re-imaged or decommissioned. Generally, it takes a while before stale computer accounts pile up in significant numbers, but it will happen eventually.

Previously, the only way to clean up these accounts was with a script. (For an example of such a script, go to and click the Perl link in item 8.8.) But now there is a much easier way. With OldCmp, you can search for, disable, or delete inactive computer accounts. Even better, you can create a simple batch script to automate the process.

So how does OldCmp determine what is an inactive computer? Computers with Windows OSs that are members of a domain automatically change their password every 30 days. A computer object's pwdLastSet attribute stores the age of the computer's password. Technically, you could write a query that searches AD for computers whose pwdLastSet value is greater than the specified number of months. Unfortunately, manually writing this query is difficult. The pwdLastSet attribute's value has the Large Integer data type, so you have to perform some special calculations to come up with the correct value to use. With OldCmp, you can avoid this hassle.

Because OldCmp and AdFind were written by the same guy (i.e., Joe), OldCmp has many of the same command-line options as AdFind. Specifically, the -b, -h, -s, and -f options I described previously all work in the same manner, except in this case, they're used as search criteria to find inactive computer accounts. To be safe, you shouldn't consider a computer inactive unless its password is more than 90 days old (which is the default in OldCmp). To be really safe, you might want to consider a computer inactive only when its password is older than 180 days. To specify an age other than the default of 90 days, you use the -age option.

When you use OldCmp to perform a search, you must specify at least one of three possible options: -report (generates an HTML report listing the inactive computer accounts), -disable (disables inactive computer accounts), or -delete (deletes inactive computer accounts). If you run OldCmp with only the -report option, it searches for all computer objects in your default domain that have a password age greater than 90 days and generates an HTML report with the results. If you have a large domain with lots of computer accounts, it might take a while for the command to complete. To reduce the amount of time it takes for OldCmp to run, you can use the -b option to target a specific OU.

The HTML file that OldCmp generates will be in the same directory that you run the tool from, unless you specify an alternative location with the -file option. If you include the -sh option, OldCmp automatically opens the HTML file after it's generated.

If you want to regularly generate an HTML report, all you need to do is create a batch (.bat) file that contains only two lines of code, as Listing 1 shows. The first line runs OldCmp, whereas the second line runs Blat, a command-line tool for sending the contents of a file in an email message. You can download Blat from In the second line, make sure you customize the -to option with your email address. In addition, make sure you put both OldCmp and Blat in your run path (i.e., the path defined in the PATH environment variable).

After you create the batch file, you need to create a scheduled task. Be sure to specify a domain user account and password for the job so the script has sufficient permissions to query computer objects in the domain.

Identifying inactive computer accounts is helpful, but more than likely, you'll want to clean up those accounts at some point. My general recommendation is to first disable inactive computer accounts, then after a week or month, delete the disabled computer accounts. This waiting period acts as a safety valve to ensure no one is using the computer accounts.

Listing 2 contains a batch file that deletes disabled computer accounts and disables newly found inactive computer accounts. This batch file contains two sets of commands. (Be sure you don't swap the order.) The first set uses OldCmp to delete any disabled computer accounts and create the deleted_comps.html report, then uses Blat to email that report to The second set uses OldCmp to disable all computer accounts whose passwords are older than 180 days and create the disabled_comps.html report, then uses Blat to email that report.

When creating OldCmp, Joe was concerned about people accidentally deleting or disabling thousands of computer accounts, so he added several precautions, including the -safety and -forreal options you see in both sets of commands. The -safety option limits the number of accounts the script can delete or disable. By default, OldCmp won't delete or disable more than 10 accounts. Including the -safety option with a value of 100 tells OldCmp that it's okay to delete as many as 100 accounts. The -forreal option tells OldCmp that it's okay to delete or disable the accounts. Without the -forreal option, OldCmp just reports on the accounts it would delete or disable--it doesn't actually delete or disable them.

Before you use the batch file in Listing 2, you need to customize the email address in the two Blat commands. In addition, for testing purposes, you should remove the -forreal option from the two OldCmp commands, then run the batch file to make sure you're okay with the accounts OldCmp will delete and disable.

AD is often touted for its flexible delegation of administration feature. For a particular security principal, you can restrict access all the way down to the attribute level. Microsoft provides a Delegation of Control Wizard that can walk you through the process of delegating administration for certain types of tasks. You can also use the ACL editor to tweak ACLs even further.

Although it's easy to delegate access to a particular account, it hasn't been so easy to undelegate the access--that is, until now. Microsoft recently created a tool called Dsrevoke that lets you iterate over the contents of an OU and remove all access control entries (ACEs) that contain a specific security principal. So, for example, if you created a complex delegation for a group called Help Desk, you can use Dsrevoke to go back and remove all the ACEs that contain the Help Desk security principal. That capability makes Dsrevoke a nice tool to have. So run, don't walk, to your computer and download Dsrevoke (

With Dsrevoke, you can either search for (/report option) or delete (/remove option) the ACEs that have a particular security principal. To use Dsrevoke, you specify the /report or /remove option, then use the /root option to specify a root from which to start the search or delete operation. You end the command with the name of the security principal you want to search for or remove. For example, here's a command that searches the Workstations OU for all ACEs that contain the Data Admins security principal:

dsrevoke /report /root:ou=workstations,
  "RALLENCORP\Data Admins"

As Figure 3 shows, the Workstations OU has two ACEs that contain the Data Admins security principal. To delete these ACEs, you run the same command, except you replace /report with /remove:

dsrevoke /remove /root:ou=workstations,
  "RALLENCORP\Data Admins"

You'll get the same output as before, except you'll be prompted about whether you want to delete the ACEs.

One limitation you need to be aware of is that Dsrevoke works only against OUs or a domain root. It won't work against containers such as the default Computers (cn=Computers) or Users (cn=Users) containers.

Ever wonder what happens to an object in AD when you delete it? When you delete an object, it doesn't disappear completely. Instead, the object becomes a tombstone. After 60 days (the default tombstone lifetime period), the tombstone is permanently deleted.

Before the release of Windows 2003, there was no method for bringing tombstones back to life. Now, you can at least partially restore deleted objects--and Sysinternals' AdRestore utility ( makes it a snap.

To enumerate all current deleted objects in the current domain, you run AdRestore with no options:


Figure 4 shows sample results from this command.

If you want to restore a tombstone, you use the -r option followed by the name of the object to restore. For example, the following command restores the John Billings user account:

adrestore -r "John Billings"

The output from this command will be similar to that in Figure 4, except you'll be prompted about whether you want to restore the object. As I mentioned previously, AdRestore only partially restores the object. The tombstone doesn't retain all the attributes of the original object. For details about the process behind restoring deleted objects, see the Security Administrator article "AD Tombstone Objects," March 2004, InstantDoc ID 41576.

No More Excuses
By familiarizing yourself with AdFind, AdMod, OldCmp, Dsrevoke, and AdRestore, you can increase your effectiveness as an AD administrator. These beefed-up command-line tools make it easy to do tasks that were once tedious or difficult. And because all the tools are free, you have no excuse for not adding them to your AD toolbox.

Learning Path
If you found the five command-line tools interesting but had trouble understanding the batch files, check out these tutorials:
"Shell Scripting 101," InstantDoc ID 16355
"Getting Started in NT Shell Scripting, Part 1," InstantDoc ID 8182
"Getting Started in NT Shell Scripting, Part 2," InstantDoc ID 8384
If you found the five command-line tools interesting and you want to learn about other useful command-line tools, check out these articles:
"AD Tools for the Shell Script Writer," InstantDoc ID 39632
"Command-Line Scripting Tools in Windows 2003," InstantDoc ID 39537
"Take Command of Your Management Tasks," InstantDoc ID 16426
"Win2K Command-Line Utilities," InstantDoc ID 16250

If you want to learn about AD, check out the Microsoft Active Directory series at