Windows Server 2003 Directory Service Tools
Work with AD objects from the command line
September 12, 2004
As an administrator of an Active Directory (AD) domain, at some point you're going to want to perform some typical AD management tasks for multiple objects in one operation. You can automate many tasks in Windows 2000 if you're skilled in Windows Script Host (WSH) and Active Directory Service Interfaces (ADSI) scripting technologies, but bulk operations of common administrative tasks can be difficult without this knowledge. The Ldifde and Csvde tools provide limited support, but creating the required input files (i.e., LDAP Data Interchange Format—LDIF—and comma-separated value—CSV—files) can be tedious. Therefore, most people don't find these tools complete or easy to work with. Consequently, executing AD management operations for multiple objects under Win2K can be frustrating. Fortunately, Microsoft addressed this problem by providing a set of six directory service command-line tools in Windows Server 2003. Let's look at how to use these tools in some real-world situations that you might encounter.
6 Tools
The directory service tools are included with Windows 2003 or can be installed with the Windows 2003 Admin Pack. You can also install and run them on computers that are running Windows XP Service Pack 1 (SP1), but Microsoft doesn't recommend that you install the tools on Win2K computers. The tools can target Windows 2003 domain controllers (DCs) and Win2K DCs that have SP3 or later installed.
You use the six directory service tools to perform typical AD operations from the command line:
Dsadd adds a computer, contact, group, organizational unit (OU), quota, or user to a directory.
Dsget displays selected attributes of a computer, contact, group, OU, partition, quota, server, site, subnet, or user in a directory.
Dsmod modifies an existing computer, contact, group, OU, partition, quota, server, or user in a directory.
Dsmove moves any object (except a partition or quota) from its current location in the directory to a new location in the same domain and renames the object.
Dsquery uses specified search criteria to find a list of computers, contacts, groups, OUs, partitions, quotas, servers, sites, subnets, or users in a directory.
This tool also uses the * parameter to perform Lightweight Directory Access Protocol (LDAP) queries.Dsrm deletes from a directory any object that you specify on the command line.
In the balance of this article, I show you how to use the directory service tools from the command line. Of course, the challenge is to type these commands without any errors, but I alleviate this problem by providing CommandList.txt, which contains all the commands I use. So instead of typing the commands, you can download CommandList from the Windows Scripting Solutions Web site, cut the desired command from the file, and paste it at the Windows command prompt. (Go to http://www.windowsitpro.com/windowsscripting, enter 43753 in the InstantDoc ID text box, then click the 43753.zip hotlink.)
Creating Objects with Dsadd
Let's start by creating some users. Suppose we have a flat file containing the names of the users we want to create. For each user, the file lists the first name, a space, the last name, and a carriage return, as in the MyUsers file that Figure 2 shows. Using the Windows command shell's For statement in combination with Dsadd, we can create this set of users with one command:
For /f "tokens=1,2 delims= " %i in (MyUsers.Txt) do Dsadd user "cn=%j %i,ou=MyOU, DC=LissWare,DC=Net" -samid %i.%j
(Although the command has been split across multiple lines to fit the print newsletter format, you must type it on one line.)
The For /f statement uses a loop to parse the file content. Within the loop, the statement looks for the default space delimiter in each line, placing the first name (before the space) in the first token (%i) and the last name (after the space) in the second token (%j).
The Dsadd statement then uses the output of the For /f loop to create the users whose names are in the file. The command interpreter replaces %i with the first name and %j with the last name. As you can see, the first parameter specified for Dsadd is user, which specifies that we're creating a user object rather than a computer object, an OU object, or some other object type. The second parameter is the user's distinguished name (DN), which consists of an OU and a domain. If the OU doesn't exist, you can create it with a statement similar to
dsadd ou "OU=MyOU,DC=LissWare, DC=Net"
The last parameter, -samid, defines the sAMAccountName attribute and corresponds to the legacy logon name.
You can specify many more parameters on the command line, such as the first name (givenName attribute) and last name (sn attribute). Although you can set these properties at creation time, we'll perform this task in the next section of the article to give ourselves the opportunity to play with the Dsmod and Dsquery tools.
If you don't have much experience with command-shell commands, I recommend that you look at the online documentation provided about Windows 2003 installations. To access the documentation, open a command prompt and type
hh.exe %systemroot%help ntcmds.chm
Modifying Objects with Dsmod
Now that we've created a few users, let's set some properties for them. To update the givenName attribute by using the -fn (first name) switch and the sn attribute by using the -ln (last name) switch, we use a command similar to the one we used to create the users:
For /f "tokens=1,2 delims= " %i in (MyUsers.Txt) do Dsmod user "cn=%j %i, ou=MyOU,DC=LissWare,DC=Net" -fn "%i" -ln "%j"
By default, a user is always created in disabled mode in AD. To enable the users, we can use the same basic Dsmod command as above but with different parameters:
For /f "tokens=1,2 delims= " %i in (MyUsers.Txt) do Dsmod user "cn=%j %i, ou=MyOU,DC=LissWare,DC=Net" -disabled no -pwd Password1
Note that when you enable a user, you need to specify a password. The password is mandatory in the default Windows 2003 policies.
Although these Dsmod commands are fine for our purposes, they aren't very interesting from a tool usage point of view because they use basically the same tools and command-line structure as the Dsadd command. Querying AD to retrieve the list of users and modifying them directly would be much more fun. We can perform this task by combining Dsmod and Dsquery.
Querying AD with Dsquery
All six of the directory service tools support redirection, so you can use the output of one tool as input for another tool. For example, you can query AD for a list of users, then use the list as input for a command that sets a property for each user on the list. The command
dsquery user
returns a list of all users in AD. To find the users we created earlier in the OU called MyOU, we can use the command
dsquery user "ou=MyOU, DC=LissWare,DC=Net"
This command outputs a list of DNs that corresponds to the users we just created with Dsadd, as Figure 3 shows.
Now let's use the pipe (|) character (ASCII character 124) to redirect Dsquery's output to Dsmod, as follows:
dsquery user "ou=MyOU, DC=LissWare,DC=Net" | dsmod user -disabled no -pwd Password1
The Dsmod command uses the DN list as input and changes the state of the users in MyOU.
A similar command lets us check the success of this command by determining whether any users are still disabled:
dsquery user "ou=MyOU, DC=LissWare,DC=Net" -disabled
Now that our new users are set up and enabled, we can use Dsget to see what we configured in AD.
Retrieving Information with Dsget
To retrieve information about the AD users we've created, we start with a Dsquery command and a redirection, as we did when we enabled the users. However, this time, we'll combine Dsquery with Dsget instead of with Dsmod. The following command displays the first name, last name, and enabled or disabled state of all users in MyOU:
dsquery user "ou=MyOU, DC=LissWare,DC=Net" | dsget user -fn -ln -disabled
Figure 4 shows the command's output.
Creating a Group with Dsmod
Another useful application of the Dsquery and Dsmod combination is the creation of a security group for all MyOU members. First, we need to use Dsadd to create the security group:
dsadd group "cn=MyGroup, ou=MyOU,DC=LissWare,DC=Net" -secgrp yes -scope g
The scope g parameter tells the tool to create a global group. Next, we use the Dsquery and Dsmod combination to add all the MyOU members to the new group:
dsquery user -scope onelevel "ou=MyOU,DC=LissWare,DC=Net" | dsmod group "cn=MyGroup, ou=MyOU,DC=LissWare,DC=Net" -addmbr
Moving Users with Dsmove
Now imagine that you want to move certain users to a specific OU or container. For instance, to move user John Conner from MyOU to the Users container, the command would be:
dsmove "cn=Connor John,OU=MyOU, DC=LissWare,DC=Net" -newparent "cn=Users, DC=LissWare,DC=Net"
But what if we wanted to move all the users whose first name starts with J? We can do this by combining the Dsquery and Dsmove tools. To find all the users whose first name starts with J, you might try the command
dsquery user -name J*
Unfortunately, this command doesn't return the expected results because the -name switch performs a match on the relative DN of the user (i.e., the common name, or cn,) and we built the DN with the last name in the first position and the first name in the last position. Therefore, we can't use the standard Dsquery switches; rather, we must explicitly express the LDAP query filter that we want to use. To locate all users that have a first name that starts with J, we need to use the command
dsquery * "ou=MyOU,DC=LissWare, DC=Net" -filter "(&(objectClass=user) (givenName=J*))"
This filter returns three DNs: Jane, John, and Juliet. To carry out the move operation, we combine the above query with the appropriate Dsmove command, as follows:
For /f "delims=*" %i in ('dsquery * "ou=MyOU, DC=LissWare,DC=Net" -filter "(&(objectClass=user) (givenName=J*))"') do dsmove -newparent "cn=users, DC=LissWare,DC=Net" %i
Here, we need to use a For /f statement instead of a pipe redirection because Dsmove accepts the redirection of only one DN at a time. Dsadd has the same limitation.
Deleting Users with Dsrm
The Dsrm directory service tool removes AD objects. Dsrm requires only the DN of the object to be removed. For example, to delete the user objects we created earlier, we can use the command
dsquery user "ou=MyOU, DC=LissWare,DC=Net" | dsrm -noprompt
When you specify the -noprompt switch, Dsrm doesn't request a confirmation. To delete the group we created earlier, we can use the command
dsrm "cn=MyGroup,ou=MyOU, DC=LissWare,DC=Net" -noprompt
To delete the OU, we use the commanddsrm "ou=MyOU,DC=LissWare, DC=Net" -noprompt
To remove the three users we moved to the Users container (Jane, John, and Juliet), we use the command
dsquery * "cn=Users, DC=LissWare,DC=Net" -filter "(&(objectClass=user) (|(givenName=Jane)(givenName=John)(givenName=Juliet)))" | dsrm -noprompt
This command ensures that only users with the name Jane, John, or Juliet are deleted. We've now removed everything we created in AD.
Tool Notes
The directory service tools are especially beneficial when combined with command-shell statements such as For /f. This combination lets the directory service tools benefit from command-shell automation and lets us leverage traditional command-shell commands to carry out AD operations.
Although the directory service tools are useful, they have some limitations. You can pipe through the standard input only the DN of the object that you want to manipulate. You must specify all other parameters by using the command-line switches. It would be nice to be able to pipe the complete command line through the standard input.
The six directory service tools handle more than 80 percent of a typical shop's AD management needs, but they don't eliminate the need for WSH and ADSI scripting. Actually, "traditional" scripting is probably better than using the directory service tools when robust code-logic execution is required because the command shell offers poor error-handling features.
Bear in mind that you can call the directory service tools directly from a WSH script, so they can complement WSH and ADSI scripting. WSH 5.6 provides access to the standard I/O streams, or pipes, enabling the tools to receive input (i.e., the DN of the object you want them to work with) from a WSH script and letting a WSH script parse the execution results. For instance, a WSH script can "delegate" an AD query to Dsquery instead of using ADSI and ADO. The WSH script can receive the result of the search via the standard input stream and parse the result.
Listing 1 shows a short sample script. The script first creates the WshShell object that's used to execute the process that's passed as a parameter of the WshShell.Exec method. After checking for the successful execution of the method, the script shows the Dsquery process ID and output. The script captures the output generated by Dsquery by reading the standard output stream in a loop. The loop ends when the output stream terminates.
The directory service tools help you perform typical AD operations, such as adding, moving, and removing objects, from the command line. Combining directory service tool statements with WSH is a great way to simplify your scripting code while leveraging the features that this great set of tools provides.
The scope g parameter tells the tool to create a global group. Next, we use the Dsquery and Dsmod combination to add all the MyOU members to the new group:
dsquery user -scope onelevel "ou=MyOU,DC=LissWare,DC=Net" | dsmod group "cn=MyGroup, ou=MyOU,DC=LissWare,DC=Net" -addmbr
Moving Users with Dsmove
Now imagine that you want to move certain users to a specific OU or container. For instance, to move user John Conner from MyOU to the Users container, the command would be:
dsmove "cn=Connor John,OU=MyOU, DC=LissWare,DC=Net" -newparent "cn=Users, DC=LissWare,DC=Net"
But what if we wanted to move all the users whose first name starts with J? We can do this by combining the Dsquery and Dsmove tools. To find all the users whose first name starts with J, you might try the command
dsquery user -name J*
Unfortunately, this command doesn't return the expected results because the -name switch performs a match on the relative DN of the user (i.e., the common name, or cn,) and we built the DN with the last name in the first position and the first name in the last position. Therefore, we can't use the standard Dsquery switches; rather, we must explicitly express the LDAP query filter that we want to use. To locate all users that have a first name that starts with J, we need to use the command
dsquery * "ou=MyOU,DC=LissWare, DC=Net" -filter "(&(objectClass=user) (givenName=J*))"
This filter returns three DNs: Jane, John, and Juliet. To carry out the move operation, we combine the above query with the appropriate Dsmove command, as follows:
For /f "delims=*" %i in ('dsquery * "ou=MyOU, DC=LissWare,DC=Net" -filter "(&(objectClass=user) (givenName=J*))"') do dsmove -newparent "cn=users, DC=LissWare,DC=Net" %i
Here, we need to use a For /f statement instead of a pipe redirection because Dsmove accepts the redirection of only one DN at a time. Dsadd has the same limitation.
Deleting Users with Dsrm
The Dsrm directory service tool removes AD objects. Dsrm requires only the DN of the object to be removed. For example, to delete the user objects we created earlier, we can use the command
dsquery user "ou=MyOU, DC=LissWare,DC=Net" | dsrm -noprompt
When you specify the -noprompt switch, Dsrm doesn't request a confirmation. To delete the group we created earlier, we can use the command
dsrm "cn=MyGroup,ou=MyOU, DC=LissWare,DC=Net" -noprompt
To delete the OU, we use the commanddsrm "ou=MyOU,DC=LissWare, DC=Net" -noprompt
To remove the three users we moved to the Users container (Jane, John, and Juliet), we use the command
dsquery * "cn=Users, DC=LissWare,DC=Net" -filter "(&(objectClass=user) (|(givenName=Jane)(givenName=John)(givenName=Juliet)))" | dsrm -noprompt
This command ensures that only users with the name Jane, John, or Juliet are deleted. We've now removed everything we created in AD.
Tool Notes
The directory service tools are especially beneficial when combined with command-shell statements such as For /f. This combination lets the directory service tools benefit from command-shell automation and lets us leverage traditional command-shell commands to carry out AD operations.
Although the directory service tools are useful, they have some limitations. You can pipe through the standard input only the DN of the object that you want to manipulate. You must specify all other parameters by using the command-line switches. It would be nice to be able to pipe the complete command line through the standard input.
The six directory service tools handle more than 80 percent of a typical shop's AD management needs, but they don't eliminate the need for WSH and ADSI scripting. Actually, "traditional" scripting is probably better than using the directory service tools when robust code-logic execution is required because the command shell offers poor error-handling features.
Bear in mind that you can call the directory service tools directly from a WSH script, so they can complement WSH and ADSI scripting. WSH 5.6 provides access to the standard I/O streams, or pipes, enabling the tools to receive input (i.e., the DN of the object you want them to work with) from a WSH script and letting a WSH script parse the execution results. For instance, a WSH script can "delegate" an AD query to Dsquery instead of using ADSI and ADO. The WSH script can receive the result of the search via the standard input stream and parse the result.
Listing 1 shows a short sample script. The script first creates the WshShell object that's used to execute the process that's passed as a parameter of the WshShell.Exec method. After checking for the successful execution of the method, the script shows the Dsquery process ID and output. The script captures the output generated by Dsquery by reading the standard output stream in a loop. The loop ends when the output stream terminates.
The directory service tools help you perform typical AD operations, such as adding, moving, and removing objects, from the command line. Combining directory service tool statements with WSH is a great way to simplify your scripting code while leveraging the features that this great set of tools provides.
About the Author
You May Also Like