Google


   


You are here: CodeIdol.com > C# > C# Network Programming > Active Directory > Modifying Directory Data

SAVE
Digg
Shown on del.icio.us del.icio.us
See Whos Talking About This on Technorati Technorati
I've Reddit reddit

Modifying Directory Data

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
Start example
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 person objectClass and has two additional properties, a common name of Katie Blum, and a surname of Blum.

End example

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
Start example
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.

End example

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:

de.Properties["telephoneNumber"].Add("(111)222-3333");

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
Start example
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();
  }
}
End example

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
Start example
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:

C:\>ListObjects
LDAP://192.168.1.100/dc=ispnet1, dc=net
 child: cn=Administrator
 child: ou=accounting
 child: ou=engineering
 child: ou=sales
 child: ou=hq
C:\>

Note that all objects, no matter what object type they are, appear as child objects of the base object.

End example

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
Start example
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();
 }
}
End example

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
Start example
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");
  }
 }
}
End example
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
Start example
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());
   }
  }
}
End example

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
Start example
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();
  }
}
End example
SAVE
Digg
Shown on del.icio.us del.icio.us
See Whos Talking About This on Technorati Technorati
I've Reddit reddit

You are here: CodeIdol.com > C# > C# Network Programming > Active Directory > Modifying Directory Data


ADBRITE ads links
   
Related tags







Popular Categories
Unix books and guides

AJAX popular information
C# language guides
Windows books and cookbooks

.......








Business Key Top Sites

be number one
rate your site




    С 2009 года мы стали переводить структура сайта на различные языки. Сайт теперь будет содержать книги не только на английском языке, но также и на других европейских языках, в том числе и на Русском языке.

    Русский Polski Francais Deutsch
    support sitemap terms

© CodeIdol Labs, 2007 - 2009