4.25.4 See Also Recipe 4.24 for information on LDIF, RFC 2849 The LDAP Data Interchange Format LDIF— Technical Specification, and MS KB 237677 Using LDIFDE to Import and Export Directory
Trang 14.25.4 See Also
Recipe 4.24 for information on LDIF, RFC 2849 (The LDAP Data Interchange Format (LDIF)— Technical Specification), and MS KB 237677 (Using LDIFDE to Import and Export Directory Objects to Active Directory)
Recipe 4.26 Exporting Objects to a CSV File
4.26.1 Problem
You want to export objects to a comma-separated variable (CSV) file The CSV file can then be opened and manipulated from a spreadsheet application or with a text editor
4.26.2 Solution
4.26.2.1 Using a command-line interface
> csvde -f output.csv -l <AttrList> -p <Scope> -r "<Filter>" -d "<BaseDN>"
4.26.3 Discussion
Once you have a CSV file containing entries, you can use a spreadsheet application such as Excel to view, sort, and manipulate the data
4.26.3.1 Using a command-line interface
The parameters used by cvsde are nearly identical to those used by ldifde The -f switch specifies the name of the file to use to save the entries to, -s is the DC to query, -l is the comma-separated list of attributes to include, -p is the search scope (base, onelevel, or subtree), -r is the search filter, and -d is the base DN If you encounter any issues, the -v switch enables verbose mode and can help identify problems
4.26.4 See Also
Recipe 4.27 for importing objects using a CSV file
Recipe 4.27 Importing Objects Using a CSV File
4.27.1 Problem
You want to import objects into Active Directory using a CSV file
4.27.2 Solution
4.27.2.1 Using a command-line interface
Trang 2To import objects using the csvde utility, you must first create a CSV file containing the objects
to add The first line of the file should contain a comma-separated list of attributes you want to set, with DN being the first attribute Here is an example:
DN,objectClass,cn,sn,userAccountControl,sAMAccountName,userPrincipalName
The rest of the lines should contain entries to add If you want to leave one of the attributes unset, then leave the value blank (followed by a comma) Here is a sample CSV file that would add two user objects:
DN,objectClass,sn,userAccountControl,sAMAccountName,userPrincipalName
"cn=jim,cn=users,dc=rallencorp,dc=com",user,Smith,512,jim,jim@rallencorp.com
"cn=john,cn=users,dc=rallencorp,dc=com",user,,512,john,john@rallencorp.com
Once you've created the CSV file, you just need to run cvsde command to import the new
objects
> csvde -i -f input.csv
4.27.3 Discussion
Note that each line of the CSV import file, except the header, should contain entries to add
objects You cannot modify attributes of an object or delete objects using csvde If you have a spreadsheet containing objects you want to import, first save it as a CSV file and use csvde to import it
4.27.3.1 Using a command-line interface
To import with csvde, simply specify the -i switch to turn on import mode and -f <filename>
for the file It can also be beneficial to use the -v switch to turn on verbose mode to get more information in case of errors
4.27.4 See Also
Recipe 4.26 for exporting objects in CSV format, and MS KB 327620 (HOW TO: Use Csvde to Import Contacts and User Objects into Active Directory)
Trang 3Chapter 5 Organizational Units
Introduction
Recipe 5.1 Creating an OU
Recipe 5.2 Enumerating the OUs in a Domain
Recipe 5.3 Enumerating the Objects in an OU
Recipe 5.4 Deleting the Objects in an OU
Recipe 5.5 Deleting an OU
Recipe 5.6 Moving the Objects in an OU to a Different OU
Recipe 5.7 Moving an OU
Recipe 5.8 Determining How Many Child Objects an OU Has
Recipe 5.9 Delegating Control of an OU
Recipe 5.10 Allowing OUs to Be Created Within Containers
Recipe 5.11 Linking a GPO to an OU
Introduction
An LDAP directory, such as Active Directory, stores data in a hierarchy of containers and leaf nodes called the directory information tree (DIT) Leaf nodes are end points in the tree, while containers can store other containers and leaf nodes In Active Directory, the two most common types of containers are organizational units (OUs) and container objects The container objects are generic containers that do not have any special properties about them other than that they can contain objects Organizational units, on the other hand, have some special properties, such as being able to be linked to a group policy In most cases, when designing a hierarchy of objects in Active Directory, especially users and computers, you should use OUs instead of containers There is nothing you can do with a container that you can't do with an OU, but the reverse is not true
The Anatomy of an Organizational Unit
Organizational units can be created anywhere in a Domain naming context The one exception is that by default OUs cannot be added as a child of a container object See Recipe 5.10 for more
on how to work around this OUs are represented in Active Directory by organizationalUnit
Trang 4objects Table 5-1 contains a list of some interesting attributes that are available on
organizationalUnit objects
Table 5-1 Attributes of organizationalUnit objects
Attribute Description
description Textual description of the OU
gPLink List of group policy objects (GPOs) that have been linked to the
OU See Recipe 5.11 for more information
gpOptions Contains 1 if GPO inheritance is blocked and 0 otherwise
msDS-Approx-Immed-Subordinates
Approximate number of direct child objects in the OU See Recipe 5.8 for more information
managedBy Distinguished name (DN) of user or group that is in charge of
managing the OU
modifyTimestamp Timestamp of when the OU was last modified
createTimestamp Timestamp of when the OU was created
Recipe 5.1 Creating an OU
5.1.1 Problem
You want to create an OU
5.1.2 Solution
5.1.2.1 Using a graphical user interface
1 Open the Active Directory Users and Computers (ADUC) snap-in
2 If you need to change domains, right-click on the Active Directory Users and Computers
label 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 new OU, right-click on it, and select
New Organizational Unit
4 Enter the name of the OU and click OK
5 To enter a description for the new OU, right-click on the OU in the left pane and select
Properties
6 Click OK after you are done
5.1.2.2 Using a command-line interface
> dsadd ou "<OrgUnitDN>" -desc "<Description>"
Trang 55.1.2.3 Using VBScript
' This code creates an OU
' - SCRIPT CONFIGURATION -
strOrgUnit = "<OUName>" ' e.g Tools
strOrgUnitParent = "<ParentDN>" ' e.g ou=Engineering,dc=rallencorp,dc=com strOrgUnitDescr = "<Description>" ' e.g Tools Users
' - END CONFIGURATION -
set objDomain = GetObject("LDAP://" & strOrgUnitParent)
set objOU = objDomain.Create("organizationalUnit", "OU=" & strOrgUnit)
objOU.Put "description", strOrgUnitDescr
objOU.SetInfo
WScript.Echo "Successfully created " & objOU.Name
5.1.3 Discussion
OUs are used to structure data within Active Directory Typically, there are four reasons why you would need to create an OU:
Segregate objects
It is common practice to group related data into an OU For example, user objects and computer objects are typically stored in separate OUs (in fact, that is the default
configuration with Active Directory) One reason for this is to make searching the
directory easier
Delegate administration
Perhaps the most often used reason for creating an OU is to delegate administration With OUs you can give a person or group of people rights to do certain functions on objects within the OU
Apply a GPO
An OU is the smallest unit that a GPO can be applied to If you have different types of users within your organization that need to apply different GPOs, the easiest way to set that up is to store the users in different OUs and apply GPOs accordingly
Controlling visibility of objects
You can use OUs as a way to restrict what users can see in the directory
In each solution, the description attribute was set It is not a mandatory attribute, but it is good practice to set it so that others browsing the directory have a general understanding of the
purpose of the OU Also, consider setting the managedBy attribute to reference a user or group that is the owner of the OU
Trang 65.1.4 See Also
MS KB 308194 (HOW TO: How to Create Organizational Units in a Windows 2000 Domain)
Recipe 5.2 Enumerating the OUs in a Domain
5.2.1 Problem
You want to enumerate all containers and OUs in a domain, which effectively displays the structure of the domain
5.2.2 Solution
5.2.2.1 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, you can browse the directory structure
5.2.2.2 Using a command-line interface
The following command will enumerate all OUs in the domain of the user running the command
> dsquery ou domainroot
5.2.2.3 Using VBScript
' This code recursively displays all container and organizationalUnit
' objects under a specified base Using "" for the second parameter means ' that there will be no indention for the first level of objects displayed
DisplayObjects "LDAP://<DomainDN>", ""
' DisplayObjects takes the ADsPath of the object to display
' child objects for and the number of spaces (indention) to
' use when printing the first parameter
Function DisplayObjects( strADsPath, strSpace)
set objObject = GetObject(strADsPath)
Wscript.Echo strSpace & strADsPath
objObject.Filter = Array("container","organizationalUnit")
for each objChildObject in objObject
DisplayObjects objChildObject.ADsPath, strSpace & " "
next
End Function
5.2.3 Discussion
5.2.3.1 Using a graphical user interface
Trang 7If you want to expand all containers and OUs within an OU, you have to manually expand each one within ADUC; there is no "expand all" option
5.2.3.2 Using a command-line interface
To enumerate both OUs and containers, you have to a use a more generic dsquery command The following command will display all containers and OUs in the domain of the user running the command:
> dsquery * domainroot -filter
"(|(objectcategory=container)(objectcategory=organizationalunit))" -scope subtree
-limit 0
5.2.3.3 Using VBScript
When iterating over the contents of an OU using a for each loop, paging will be enabled so that all child objects will be returned (instead of only 1,000 per the administrative limit) In order to display all child container objects regardless of depth, I used a recursive function called
DisplayObjects
Recipe 5.3 Enumerating the Objects in an OU
5.3.1 Problem
You want to enumerate all the objects in an OU
5.3.2 Solution
The following solutions will enumerate all the objects directly under an OU Look at the
Discussion section for more on how to display all objects under an OU regardless of depth
5.3.2.1 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, browse to the OU you want to view
4 Click on it The contents of the OU will be displayed in the right pane
5.3.2.2 Using a command-line interface
> dsquery * "<OrgUnitDN>" -limit 0 -scope onelevel
5.3.2.3 Using VBScript
set objOU = GetObject("LDAP://<OrgUnitDN>")
for each objChildObject in objOU
Trang 8next
5.3.3 Discussion
5.3.3.1 Using a graphical user interface
By default, ADUC will display only 2,000 objects To view more than 2000 objects, select View Filter Options In the box beside Maximum number of items displayed per folder:, put the maximum number of objects you want to display
5.3.3.2 Using a command-line interface
Using -limit 0, all objects under the OU will be displayed If -limit is not specified, 100 will
be shown by default You can also specify your own number if you want to only display a limited number of objects
The -scope onelevel option causes only direct child objects of the OU to be displayed If you want to display all objects regardless of depth, add -scope subtree
5.3.3.3 Using VBScript
When a for each loop iterates over the contents of an OU, paging will be enabled so that all child objects will be returned regardless of how many there are If you want to display all child objects regardless of depth, you have to implement a recursive function, such as the following: ' Using "" for the second parameter means that the there will be no
' indention for the first level of objects displayed
DisplayObjects "LDAP://<OrgUnitDN>", ""
' DisplayObjects takes the ADsPath of the object to display child
' objects for and the second is the number of spaces (indention)
' to use when printing the first parameter
Function DisplayObjects( strADsPath, strSpace)
set objObject = GetObject(strADsPath)
Wscript.Echo strSpace & strADsPath
for each objChildObject in objObject
DisplayObjects objChildObject.ADsPath, strSpace & " "
next
End Function
This code is nearly identical to that shown in Recipe 5.2 The only difference is that I didn't use the Filter method to restrict the type of objects displayed
Trang 9Recipe 5.4 Deleting the Objects in an OU
5.4.1 Problem
You want to delete all the objects in an OU, but not the OU itself
5.4.2 Solution
5.4.2.1 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, browse to the OU that contains the objects you want to delete and click
on it
4 Highlight all the objects in the right pane and hit the Delete button
5 Press F5 to refresh the contents of the OU If objects still exist, repeat the previous step
5.4.2.2 Using a command-line interface
To delete all objects within an OU, but not the OU itself, you need to use the -subtree and -exclude options with the dsrm command
> dsrm "<OrgUnitDN>" -subtree -exclude
5.4.2.3 Using VBScript
' This code deletes the objects in an OU, but not the OU itself
set objOU = GetObject("LDAP://<OrgUnitDN>")
for each objChildObject in objOU
Wscript.Echo "Deleting " & objChildObject.Name
objChildObject.DeleteObject(0)
next
5.4.3 Discussion
If you want to delete the objects in an OU and recreate the OU, you can either delete the OU itself, which will delete all child objects, or you could just delete the child objects The benefits
to the later approach is that you do not need to reconfigure the ACL on the OU or relink GPOs
5.4.4 See Also
Recipe 5.3 for enumerating objects in an OU, Recipe 5.5 for deleting an OU, and MSDN:
IADsDeleteOps::DeleteObject
Trang 10Recipe 5.5 Deleting an OU
5.5.1 Problem
You want to delete an OU and all objects in it
5.5.2 Solution
5.5.2.1 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, browse to the OU you want to delete, right-click on it, and select Delete
4 Click Yes
5 If the OU contains child objects, you will be asked for confirmation again before deleting
it Click Yes
5.5.2.2 Using a command-line interface
To delete an OU and all objects contained within, use the -subtree option with the dsrm
command If you don't use -subtree and the object you are trying to delete has child objects, the deletion will fail
> dsrm "<OrgUnitDN>" -subtree
5.5.2.3 Using VBScript
' This code deletes an OU and all child objects of the OU
set objOU = GetObject("LDAP://<OrgUnitDN>")
objOU.DeleteObject(0)
5.5.3 Discussion
Deleting OUs that do not contain objects is just like deleting any other type of object Deleting
an OU that contains objects requires a special type of delete operation The "Tree Delete" LDAP control (OID: 1.2.840.113556.1.4.805) must be used by the application or script to inform AD to delete everything contained in the OU All three solutions in this case use the control "under the covers," but if you were going to perform the operation via an LDAP, such as LDP, you would need to enable the control first
5.5.4 See Also
Recipe 4.3 for using LDAP controls and MSDN: IADsDeleteOps::DeleteObject