[ Team LiB ] |
28.4 DirectoryEntry BasicsThe DirectoryEntry class contains several properties to access the attributes of Active Directory objects. The following code shows how to display the currentTime attribute of the RootDSE: Dim objRootDSE As New DirectoryEntry("LDAP://RootDSE") Console.WriteLine(objRootDSE.Properties("currentTime")(0)) In the code, once we instantiated the DirectoryEntry object, we can access the currentTime attribute by passing it to the Properties property. The Properties property actually returns a collection of values for the attribute in the form of a PropertyCollection class, which is why we needed to specify an index of 0 to get at a specific value. If the currentTime attribute was multivalued, we could get at the other values by incrementing the index to 1 and so on.
Now let's look at how to display all of the values for all of the attributes of an object in Active Directory. Again we will use RootDSE as the object we want to display: Dim objRootDSE As New DirectoryEntry("LDAP://RootDSE") Dim strAttrName As String Dim objValue As Object For Each strAttrName In objRootDSE.Properties.PropertyNames For Each objValue In objRootDSE.Properties(strAttrName) Console.WriteLine(strAttrName & " : " & objValue.ToString) Next objValue Next strAttrName As you can see, the Properties property, which returns a PropertyCollection, has a PropertyNames property that returns a collection of attribute names for the Active Directory object. We loop over each attribute name and then loop over each value for that attribute to ensure we print out values for all single- and multivalued attributes. The ToString property converts whatever value is stored in the attribute to a printable string. There are several properties available in the DirectoryEntry class. Table 28-2 contains a list of them.
One interesting property to note is Children, which returns a DirectoryEntries collection containing each child object. Using the Children property, you can quickly traverse a directory tree. The following code prints out the entire directory tree rooted at dc=mycorp,dc=com: Sub Main( ) Dim objADObject As New DirectoryEntry("LDAP://dc=mycorp,dc=com") DisplayChildren(objADObject, " ") End Sub Sub DisplayChildren(ByVal objADObject As DirectoryEntry, _ ByVal strSpaces As String) Console.WriteLine(strSpaces & objADObject.Name) Dim objChild As New DirectoryEntry( ) For Each objChild In objADObject.Children DisplayChildren(objChild, strSpaces & " ") Next objChild End Sub The DisplayChildren( ) subroutine is recursive. For each child that is found, DisplayChildren( ) is called again, and so on until no child objects are found. The strSpaces variable is used to indent each child so that you can see the hierarchy when printed out. Now let's say that we wanted to traverse the tree but print out only the Organizational Units. To do that, we can use the SchemaClassName property for each object and only print out the entry if its SchemaClassName equals organizationalUnit, which is the objectClass value for OUs. Sub Main( ) Dim objADObject As New DirectoryEntry("LDAP://dc=mycorp,dc=com") DisplayChildren(objADObject, " ") End Sub Sub DisplayChildren(ByVal objADObject As DirectoryEntry, _ ByVal strSpaces As String) If objADObject.SchemaClassName = "organizationalUnit" Then Console.WriteLine(strSpaces & objADObject.Name) End If Dim objChild As New DirectoryEntry( ) For Each objChild In objADObject.Children DisplayChildren(objChild, strSpaces & " ") Next objChild End Sub
We are now going to take many of the concepts described so far and make a fully functional program. Let's expand on the first example we covered that printed the attributes and values for the RootDSE. We are going to turn it into a program that can accept a command-line argument, which should be the ADsPath of an object, and then display all of the attributes and values for that object. Example 28-1 contains the code. Example 28-1. Making a fully functional programImports System Imports System.DirectoryServices Module Module1 Sub Main( ) Dim cmd As String ' Read the commandline and get the number of arguments passed Dim intArgs As Integer Try intArgs = Environment.GetCommandLineArgs( ).Length( ) Catch exp As Exception ' Set intArgs to 0 if no arguments were passed intArgs = 0 End Try ' If an argument was specified on the commandline, set ' strADsPath to that, if not default to query the RootDSE Dim strADsPath As String If intArgs > 1 Then strADsPath = Environment.GetCommandLineArgs( )(1) Else strADsPath = "LDAP://RootDSE" End If ' We need to see if the object in strADsPath exists ' and if not, print an error and return Dim objADObject As New DirectoryEntry( ) Try If objADObject.Exists(strADsPath) = False Then Throw (New Exception("Object does not exist")) End If Catch exp As Exception Console.WriteLine("Error retrieving object: " & strADsPath) Return End Try ' Iterate over each attribute of the object and print its values Dim strAttrName As String Dim objValue As Object Try objADObject.Path = strADsPath Console.WriteLine("Displaying " & objADObject.Path) For Each strAttrName In objADObject.Properties.PropertyNames For Each objValue In objADObject.Properties(strAttrName) Console.WriteLine(strAttrName & " : " & objValue.ToString) Next objValue Next strAttrName Catch exp As Exception Console.WriteLine("Fatal error accessing: " & strADsPath) Return End Try End Sub End Module The first two lines, which use the Imports keyword, allow us to specify class names contained within those namespaces without fully qualifying them. For example, by using Imports we can use the following code: New DirectoryEntry( ) instead of : New System.DirectoryServices.Directory( ) For simplicity, we put the rest of the code directly in the Main( ) subroutine. The first part of the code attempts to read the command line using the System.Environment namespace to see if a parameter was specified. A Try Catch statement was used because the call to Environment.GetCommandLineArgs( ).Length( ) will throw an exception if no parameters are passed on the command line. For more information on error handling, see the "Error Handling in VB.NET" sidebar. Note that the intArgs variable will contain the number of arguments passed to the script including the script name as the first argument. To see if the user actually passed the ADsPath we have to check whether intArgs > 1. It is for this reason that we set the strADsPath variable to the value specified on the command line and if one wasn't, default to the RootDSE. Next we use the Exists( ) method (not property) to determine if the object specified in strADsPath actually exists. The DirectoryEntry class contains a host of methods in addition to the properties we showed earlier. Table 28-3 contains a list of all the DirectoryEntry methods.
If the Exists( ) check fails, we generate an exception using Throw( ). If the object exists, we proceed to iterate over each attribute, printing the values for it. To turn the code into an executable, you can compile the program by selecting Build Build Solution from the VS.NET menu. If any errors are found, they are displayed in the bottom pane. If none are found, you can then execute the program. If we named the project EntryQuery, an example command line would look like the following: D:\Visual Studio Projects\EntryQuery\EntryQuery\bin> entryquery.exe LDAP:// dc=mycorp,dc=com |
[ Team LiB ] |