Modifying objects with System.DirectoryServices can be done a couple of different ways. To modify an attribute that currently has a value, you can set it using the Properties property. For example, the following code would modify the givenName attribute:
objADObject.Properties("givenName")(0) = "Robert"
If you want to set an attribute that was previously unset, you must use the Properties.Add method. The following code would set the previously unset sn attribute:
To determine whether an attribute has been set, you can use Properties("attributename").Count, which will return the number of values that have been set for the attribute. Just like with ADSI, all modifications are made initially to the local property cache and must committed to the server. With ADSI you would use the IADs::SetInfo( ) method, and with System.DirectoryServices it is called CommitChanges( ), which is available from the DirectoryEntry class.
Now that we covered how to set an attribute, we can modify the earlier code that printed all the values of an attribute to instead set an attribute. The code in Example 28-2 expects three command line parameters: the first is the ADsPath of the object to modify, the second is the attribute name, and the third is the value to set the attribute to.
Dim strADsPath As String Dim strAttrName As String Dim strAttrValue As String Try Dim intArgs As Integer = Environment.GetCommandLineArgs( ).Length( ) If intArgs <> 4 Then Throw (New Exception("All parameters are required")) Else strADsPath = Environment.GetCommandLineArgs( )(1) strAttrName = Environment.GetCommandLineArgs( )(2) strAttrValue = Environment.GetCommandLineArgs( )(3) End If Catch objExp As Exception Console.WriteLine("Error: " & objExp.Message) Console.WriteLine("Usage: " & Environment.GetCommandLineArgs( )(0) & _ " ADsPath AttributeName Attribute Value") Console.WriteLine( ) Return End Try Dim objADObject As New DirectoryEntry( ) Try If objADObject.Exists(strADsPath) = False Then Throw (New Exception("Object does not exist")) End If Catch objExp As Exception Console.WriteLine("Error retrieving object: " & strADsPath) Console.WriteLine("Error: " + objExp.Message) Return End Try Dim strOldValue As String Try objADObject.Path = strADsPath If objADObject.Properties(strAttrName).Count > 0 Then strOldvalue = objADObject.Properties(strAttrName)(0) objADObject.Properties(strAttrName)(0) = strAttrValue Else objADObject.Properties(strAttrName).Add(strAttrValue) End If objADObject.CommitChanges( ) Catch objExp As Exception Console.WriteLine("Error setting object: " & strADsPath) Console.WriteLine("Error: " + objExp.Message) Return End Try Console.WriteLine(strADsPath) Console.WriteLine("Attribute: " + strAttrName) Console.WriteLine("Old value: " + strOldValue) Console.WriteLine("New value: " + strAttrValue) Console.WriteLine( ) Console.WriteLine("Update Successful")
This code is not terribly different from Example 28-1 earlier in the chapter. The main difference is the check for additional command-line parameters and the determination of whether the attribute that was specified on the command line was set previously.
Adding objects with System.DirectoryServices is similar in nature to ADSI. You must first get a reference to the parent object and then add a child. You can add a child by using the Children.Add( ) method of a DirectoryEntry object. The following example shows how to create a user object:
Dim objParent As New DirectoryEntry("LDAP://ou=sales,dc=mycorp,dc=com", _ "email@example.com",_ "MyPassword", _ AuthenticationTypes.Secure) Dim objChild As DirectoryEntry = objParent.Children.Add("cn=jdoe", "user") objChild.Properties("sAMAccountName").Add("jdoe") objChild.CommitChanges( ) objChild.NativeObject.AccountDisabled = False objChild.CommitChanges( ) Console.WriteLine("Added user")
You may have noticed several things. First, when we instantiated the DirectoryEntry object, we passed three additional parameters that we haven't used before. The second parameter is the user to authenticate with, the third is the password for the user, and the last is any authentication options from the AuthenticationTypes enumeration (ADS_AUTHENTICATION_ENUM in ADSI). After the first CommitChanges( ) call, the object is created in Active Directory. After that we enable the account by calling ADSI's AccountDisabled method. System.DirectoryServices does not duplicate all of the functionality of ADSI. As we said earlier, it is primarily a wrapper around ADSI. One of the reasons System.DirectoryServices is so powerful is that you can still access native ADSI interfaces by using the NativeObject method. NativeObject will return the IADs interface of the specific type of object. In our previous example, NativeObject will return an IADsUser object, which we can then call the IADsUser::AccountDisabled method on. A final CommitChanges( ) call will update Active Directory and enable the account.
This concludes our introduction to the .NET Framework and the System.DirectoryServices namespace. The information we covered should be sufficient to get you started writing Active Directory applications with .NET, but if you need additional information, check out MSDN, which contains detailed documentation on the .NET class library, including System.DirectoryServices.