ONDotNet.com    
 Published on ONDotNet.com (http://www.ondotnet.com/)
 See this if you're having trouble printing code examples


O'Reilly Book Excerpts: Active Directory Cookbook

Cooking with Active Directory, Part 2

Related Reading

Active Directory Cookbook
By Robbie Allen

Editor's note: In the previous batch of recipes we presented from Active Directory Cookbook we covered how to find the domain controllers that are acting as one of the FSMO roles, and how to determine the last time a user logged into a domain. This week we offer a recipe from Chapter 6 ("Users") on modifying an attribute for several users at once, and another from Chapter 7 ("Groups") on viewing the nested members of a group.

Recipe 6.4: Modifying an Attribute for Several Users at Once

Problem

You want to modify an attribute for several users at once.

Solution

Using a graphical user interface

TIP:   This requires the Windows Server 2003 version of the Active Directory Users and Computers snap-in.

  1. Open the Active Directory Users and Computers (ADUC) snap-in.
  2. If you need to change domains, right-click on "Active Directory Users and Computers" in the left pane, select Connect to Domain, enter the domain name, and click OK.
  3. In the left pane, browse to the parent container of the objects you want to modify.
  4. In the right pane, highlight each object you want to modify, right-click and select Properties.
  5. Check the box beside the attribute(s) you want to modify and edit the fields for the attributes.
  6. Click OK.

Using a command-line interface

The following command sets the home directory of all users under a parent container (<ParentDN>) to be on a particular file server (<FileServer>). The user (i.e., $username$) is automatically replaced with the sAMAccountName for the user.

> for /F "usebackq delims=""" %i in (`dsquery user "<ParentDN>" -limit 0 
-scope onelevel`) do dsmod user -hmdir "\\<FileServerName>\$username$" %i

Using VBScript

' This code sets the home drive of all users under a container
' to be on a file server where the share name is the same as the user's
' sAMAccountName.
set objParent = GetObject("LDAP://<ParentDN>")
objParent.Filter = Array("user")
for each objUser in objParent
    Wscript.Echo "Modifying " & objUser.Get("sAMAccountName")
    objUser.HomeDirectory = "\\<FileServerName>\" & _
                            objUser.Get("sAMAccountName")
    objUser.SetInfo
next

Discussion

It is often necessary to update several users at once due to an organizational, locational or file server change. In each solution, I showed how to modify all users within a parent container, but you may need to use different criteria for locating the users.

With ADUC, you are limited to modifying multiple users that belong to the same container. You can, however, create a Saved Query with the Windows Server 2003 version of ADUC that returns users based on any criteria you specify. You can then highlight those users and modify them as described in the GUI solution.

With the CLI solution, you can modify the dsquery user command to search on whatever criteria you want. The same applies in the VBScript solution, but you'll need to use an ADO query instead of the Filter method if you want to do anything more complex. See Recipe for more information on searching with ADO.

Recipe 7.3: Viewing the Nested Members of a Group

Problem

You want to view the nested members of a group.

Solution

Using a graphical user interface

  1. Open the Active Directory Users and Computers snap-in.
  2. If you need to change domains, right-click on Active Directory Users and Computers in the left pane, select Connect to Domain, enter the domain name, and click OK.
  3. In the left pane, right-click on the domain and select Find.
  4. Enter the name of the group and click Find Now.
  5. Double-click on the group in the bottom results pane.
  6. Click the Members tab.
  7. You now have to double-click on each group member to view its membership.

Using a command-line interface

> dsget group "<GroupDN>" -members -expand

Using VBScript

' This code prints the nested membership of a group.
' ------ SCRIPT CONFIGURATION ------
strGroupDN = "<GroupDN>"  ' e.g. cn=SalesGroup,ou=Groups,dc=rallencorp,dc=com
' ------ END CONFIGURATION ---------
 
strSpaces  = " "
set dicSeenGroupMember = CreateObject("Scripting.Dictionary")
Wscript.Echo "Members of " & strGroupDN & ":"
DisplayMembers "LDAP://" & strGroupDN, strSpaces, dicSeenGroupMember
 
Function DisplayMembers ( strGroupADsPath, strSpaces, dicSeenGroupMember)
 
   set objGroup = GetObject(strGroupADsPath)
   for each objMember In objGroup.Members
      Wscript.Echo strSpaces & objMember.Name
      if objMember.Class = "group" then
         if dicSeenGroupMember.Exists(objMember.ADsPath) then
            Wscript.Echo strSpaces & "   ^ already seen group member " & _
                                     "(stopping to avoid loop)"
         else
            dicSeenGroupMember.Add objMember.ADsPath, 1
            DisplayMembers objMember.ADsPath, strSpaces & " ", _
                           dicSeenGroupMember
         end if
      end if
   next
 
End Function

Discussion

As described in "Viewing the Direct Members of a Group," group membership is stored in the multivalued member attribute on group objects. But that attribute will not show the complete picture because group nesting is allowed in Active Directory after you've transitioned from mixed mode. To view the complete group membership, you have to recurse through each group's members.

In the VBScript example, I used a dictionary object (referred to as a hash or associative array in other languages) to ensure I did not get in an infinite loop. The dictionary object stores each group member; before the DisplayMembers function is called a check is performed to determine if the group has already been evaluated. If so, a message is displayed indicating the group will not be processed again. If this type of checking was not employed and you had a situation where group A was a member of group B, group B was a member of group C, and group C was a member of group A, the loop would repeat without terminating.

See Also

"Viewing the Direct Members of a Group" for viewing group membership and MSDN: IADsMember


Return to ONDotnet.com

Copyright © 2009 O'Reilly Media, Inc.