After you bind a variable to the network directory service object, you can use the DirectoryEntry properties and methods to retrieve and manipulate either the object itself or its attributes.
Warning
Within the .NET ADSI libraries, object attributes are referred to as properties. Don’t get confused by this change in terminology.
Working with Object Properties
The Properties property of a DirectoryEntry object accesses all the properties associated with the object. The Properties property returns a PropertyCollection class object, which can be manipulated to work with the various object properties.
Listing Object Properties
The PropertyCollection class contains the PropertyNames and Values properties, which get the existing object properties and their values:
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/dc=ispnet1, dc=net");
PropertyCollection pc = de.Properties
foreach(string propName in pc.PropertyNames)
Console.WriteLine("property: {0}", propName);
To obtain the value of the objectClass property, use the Properties property. Using the property name as an array index retrieves each value. The following statement retrieves the objectClass property of the object:
string value = de.Properties["objectClass"];
Listing 15.2, GetProperties.cs, is a brief example of how to iterate through all of the properties of an object and display the values of each property.
Listing 15.2: The GetProperties.cs program
using System;
using System.DirectoryServices;
class GetProperties
{
public static void Main()
{
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/cn=kblum, ou=sales, dc=ispnet1, dc=net");
Console.WriteLine("object: {0}", de.Path);
PropertyCollection pc = de.Properties;
foreach(string propName in pc.PropertyNames)
{
foreach(object value in de.Properties[propName])
Console.WriteLine(" property = {0} value = {1}",
propName, value);
}
}
}
The first foreach statement iterates through the PropertyCollection, finding all the property names associated with the object. The second foreach statement then extracts the property value(s) associated with each property name. Here’s the output from this example:
C:\>GetProperties
object: LDAP://192.168.1.100/cn=kblum, ou=sales, dc=ispnet1, dc=net
property = objectClass value = person
property = cn value = Katie Blum
property = sn value = Blum
C:\>
The output shows that the object cn=kblum, ou=sales, dc=ispnet1, dc=net is a personobjectClass and has two additional properties, a common name of Katie Blum, and a surname of Blum.
Modifying Properties
After you have the property name, you can use it to modify the value assigned to the property. There is only one catch to this: the database information may be cached on your system.
The ADSI system contains a mechanism for caching information that is retrieved from the directory service server. Any operation performed on this data is done in the system cache. There are two ways to get the data changes to take affect on the actual directory services database:
Use the CommitChanges() method to force any changes made to the cache to the directory services server
Set the UsePropertyCache property to false, ensuring that any database changes are immediately sent to the server
Either way of saving database changes will work in the AD environment. If you are making database changes over a period of time, you may want to use the UsePropertyCache property to ensure that all of the changes are being made in case of a system failure. On the other hand, if you are making lots of changes in a short period of time, it will be faster to make them in the cache and commit the changes all at once using the CommitChanges() method.
Listing 15.3 shows the ModifyProperty.cs program, which demonstrates how to modify a property value of an object in the directory services database.
Listing 15.3: The ModifyProperty.cs program
using System;
using System.DirectoryServices;
class ModifyProperty
{
public static void Main()
{
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/cn=kblum, ou=sales, dc=ispnet1, dc=net",
"cn=Administrator, dc=ispnet1, dc=net", "password",
AuthenticationTypes.ServerBind);
de.Properties["sn"][0] = "Mullen";
de.CommitChanges();
Console.WriteLine("New property value: {0}", de.Properties["sn"][0]);
de.Close();
}
}
Because the object property in the database is being modified, you will probably have to include a username and password (and possibly an AuthenticationTypes value) for the directory services server.
Note that the property value itself must be referenced using a two-dimensional array. The first element of the array is the property name, and the second element is the property value index. This shows that properties may have more than one value associated with them, although this is not often the case.
Adding Properties
To add a new property to an object, you must use the Add() method of the PropertyCollection class. The property to add must be a valid property of the object’s objectClass. The directory service schema contains the formal definitions of all objectClass types, along with what properties can be used with each objectClass.
The easiest way to add a new property is to reference the new property using the property name as the Properties array index and then use the Add() method:
This statement adds the telephoneNumber property to the DirectoryEntry object de and assigns a value to it, as demonstrated in Listing 15.4, AddProperty.cs.
Listing 15.4: The AddProperty.cs program
using System;
using System.DirectoryServices;
class AddProperty
{
public static void Main()
{
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/cn=kblum, ou=sales, dc=ispnet1, dc=net",
"cn=Administrator, dc=ispnet1, dc=net","password",
AuthenticationTypes.ServerBind);
de.Properties["telephoneNumber"].Add("(111)222-3333");
de.Properties["telephoneNumber"].Add("(444)555-6666");
de.CommitChanges();
de.Close();
}
}
After compiling and running the AddProperty program, you can use the GetProperties program to see if the additional properties were added:
C:\>GetProperties
object: LDAP://192.168.1.100/cn=kblum, ou=sales, dc=ispnet1, dc=net
property = objectClass value = person
property = cn value = Katie Blum
property = sn value = Blum
property = telephoneNumber value = (111)222-3333
property = telephoneNumber value = (444)555-6666
C:\>
Note
This example also demonstrates that you can often have multiple instances of a single property for an object. This feature can lead to incomplete information if you do not write your AD programs to take this into account. Remember to retrieve all instances of a property, not just the first value.
Working with Objects
Within the network directory service tree, any directory container object can have other objects as children (this is how the tree gets its structure). You can use the Children property to both add and remove children objects of an object.
Listing Child Objects
The Children property returns a DirectoryEntries object, which contains all of the children objects of the object as DirectoryEntry objects. However, the DirectoryEntries class is an IEnumerator-type class, so you can simply use a foreach statement to extract each DirectoryEntry object from the DirectoryEntries object.
Listing 15.5 shows the ListObjects.cs program, which lists all the child objects of a base object.
Listing 15.5: The ListObjects.cs program
using System;
using System.Collections;
using System.DirectoryServices;
class ListObjects
{
public static void Main()
{
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/dc=ispnet1, dc=net");
Console.WriteLine(de.Path);
DirectoryEntries des = de.Children;
foreach(DirectoryEntry entry in des)
{
Console.WriteLine(" child: " + entry.Name);
}
}
}
The ListObjects program binds a DirectoryEntry object to the object in the directory services database from which to begin listing objects. The Children property obtains the DirectoryEntries object, which is then enumerated to find each of the individual child objects. The output of the program looks like this:
Note that all objects, no matter what object type they are, appear as child objects of the base object.
Adding a Child Object
You can use the Add() method of the Children property to add new children objects and use the CommitChanges() method to ensure the new objects are stored in the directory service database. The Add() method format is as follows:
Add(string objectname, string schemaclassname)
To add a new object you must know the intended schema objectClass for the new object. Often you can copy this value from a similar object in the directory service database. Listing 15.6 is the AddObject.cs program, which demonstrates how to add a new organizationalUnit object under an existing directory context.
Note
In this example, I obtain the schema objectClass from a similar object already in the directory. You can use the same technique, or you can create new objectClass objects using other schemas.
Listing 15.6: The AddObject.cs program
using System;
using System.DirectoryServices;
class AddObject
{
public static void Main()
{
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/ou=accounting, dc=ispnet1, dc=net",
"cn=Administrator, dc=ispnet1, dc=net", "password",
AuthenticationTypes.ServerBind);
DirectoryEntries children = de.Children;
DirectoryEntry newchild = children.Add("ou=auditing", de.SchemaClassName);
newchild.Properties["ou"].Add("Auditing Department");
newchild.CommitChanges();
newchild.Close();
de.Close();
DirectoryEntry de2 = new DirectoryEntry(
"LDAP://192.168.1.100/ou=auditing, dc=accounting, dc=ispnet1, dc=net");
string newpath = de2.Path;
Console.WriteLine("new path: {0}", newpath);
de2.Close();
}
}
The AddObject program first binds to the parent of the new object and creates a DirectoryEntries object from the Children property of the parent object. The Add() method is used on the DirectoryEntries object, specifying both the name of the new object and the objectClass to use. (In this case, the objectClass is copied from the parent object, as the new object is also an organizationalUnit object.)
Remember that the new object’s distinguished name will still include the parent name (ou=auditing, ou=accounting, dc=ispnet1, dc=net, for this example).
Warning
Remember to log in to the directory services database as a user with permissions to add new objects. For Windows 2000 Active Directory Server, you may have to use the AuthenticationType.Secure technique to bind to the DirectoryEntry object.
Removing Child Objects
Only empty child objects can be removed from the AD. There are two ways to remove objects from the directory services database:
Using the DirectoryEntries Find() and Remove() methods
Using the DirectoryEntry DeleteTree() method
Using DirectoryEntries Methods
The first technique uses the Find() and Remove() methods of the DirectoryEntries class to first locate and then remove the desired object. In the following code snippet, you can see how you find an object given its name, create a DirectoryEntry object referencing the object, and use the Remove() method to remove it from the directory:
DirectoryEntries children = de.Children;
DirectoryEntry badObject = children.Find("auditing");
if (badObject != null)
children.Remove(badObject);
children.CommitChanges();
Of course, the final step is to ensure that the change is propagated to the actual directory services server.
Listing 15.7 shows the RemoveObject.cs program, which uses this technique to remove a child object. The program binds a variable to the parent of the object to remove, then uses the Find() method to bind a DirectoryEntry object to the object to remove. Next, the Remove() method is used, using the DirectoryEntry variable of the object to remove.
Listing 15.7: The RemoveObject.cs program
using System;
using System.DirectoryServices;
class RemoveObject
{
public static void Main()
{
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/ou=accounting, dc=ispnet1, dc=net",
"cn=Administrator, dc=ispnet1, dc=net", "password",
AuthenticationTypes.ServerBind);
DirectoryEntries children = de.Children;
try
{
DirectoryEntry badObject = children.Find("ou=auditing");
children.Remove(badObject);
de.CommitChanges();
Console.WriteLine("the object was removed");
} catch (Exception)
{
Console.WriteLine("the object was not found");
}
}
}
Using the DeleteTree() Method
The DiretoryEntry class includes the DeleteTree() method, which can be used for removing a bound object from the directory services database.
Warning
The DeleteTree() method can only be used on DirectoryEntry objects that are not bound, or an Exception will be thrown.
Listing 15.8 shows the DeleteObject.cs program, which demonstrates using the DeleteTree() method.
Listing 15.8: The DeleteObject.cs program
using System;
using System.DirectoryServices;
class DeleteObject
{
public static void Main()
{
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/ou=accounting, dc=ispnet1, dc=net",
"cn=Administrator, dc=ispnet1, dc=net", "password",
AuthenticationTypes.ServerBind);
DirectoryEntries children = de.Children;
try
{
DirectoryEntry badObject = children.Find("ou=auditing");
badObject.DeleteTree();
de.CommitChanges();
Console.WriteLine("the object has been deleted");
} catch (Exception e)
{
Console.WriteLine("the object was not found or deleted:");
Console.WriteLine(e.ToString());
}
}
}
When using the DeleteTree() method, you cannot delete an object that you are currently bound to. Instead, as seen in this example, you must bind to the parent object, and find the desired child object using the Find() method.
Warning
The DeleteTree() method does not allow you to delete objects that are not containers of other objects.
Renaming Child Objects
The Rename() method renames directory objects. The single parameter in the Rename() method is the new name assigned to the object:
de.Rename("cn=testing");
Warning
Use the Rename() method with caution. It affects not just the object that you rename, but also the distinguished names of any objects below that object in the directory tree.
The RenameObject.cs program in Listing 15.9 demonstrates how to rename a person object using the Rename() method.
Listing 15.9: The RenameObject.cs program
using System;
using System.DirectoryServices;
class RenameObject
{
public static void Main()
{
DirectoryEntry de = new DirectoryEntry(
"LDAP://192.168.1.100/ou=auditing, ou=accounting, dc=ispnet1, dc=net",
"cn=Administrator, dc=ispnet1, dc=net", "password",
AuthenticationTypes.ServerBind);
DirectoryEntries des = de.Children;
DirectoryEntry badObject = des.Find("cn=test");
badObject.Rename("cn=testing");
de.CommitChanges();
de.Close();
}
}
AJAX popular information C# language guides Windows books and cookbooks
.......
С 2009 года мы стали переводить структура сайта на различные языки. Сайт теперь будет содержать книги не только на английском языке, но также и на других европейских языках, в том числе и на Русском языке.