In Chapter 3, we covered how we can connect to Active Directory or ADAM, bind to an object, and perform create, read, update, and delete (CRUD) operations. In each of the scenarios, we knew exactly where our object was located in the directory in order to construct our binding string (ADsPath). What happens when we do not know where the object is located, or we want to return a number of related objects? The facilities and methods for searching the directory are distinctly different from what we have used thus far.
LDAP Searches in ADSI
In ADSI, we had two sets of technologies that allowed us to search Active Directory. First, for automation languages like Visual Basic 6 and VBScript, we had ADO and its OleDb LDAP provider. This provider allowed us to use either a SQL-like syntax to specify our search, or a more typical LDAP style, and behind the scenes, ADO would connect to the OleDb provider, which in turn would connect to ADSI and the IDirectorySearch interface, which would ultimately connect to the native Win32 LDAP library that would perform the search. A number of layers were involved there, as well as some clunkiness in terms of trying to use an ADO Recordset to represent a hierarchical tree of data or to specify advanced search options, but it was easy to use and it performed relatively well.
On the other side, C/C++ developers could bypass all of the ADO and OleDb layers and directly tap into the ADSI IDirectorySearch interface, a low-level, nonautomation interface that is not available to scripting languages. This was a powerful alternative, but its downside was in the details. IDirectorySearch forces the developer to deal with many structures and pointers that need to be freed properly, and it requires significant chunks of code to properly initialize a search and interpret the results. The C++ requirement scares away most developers right off the bat, and the complexity of using the interface deters many more that try.
LDAP Searches in System.DirectoryServices
In System.DirectoryServices (SDS), we use the DirectorySearcher class to query the directory and read the attributes of the objects found. DirectorySearcher is the class that makes SDS so much more powerful than traditional ADSI scripting. It combines the ease of use of typical .NET Framework classes, while providing the full compliment of search features. Like ADO, it wraps the ADSI IDirectorySearch interface and all of its messy details. However, since the object model is specifically tailored to support LDAP searches, we are not compelled to accept any of the compromises forced on us by the ADO Recordset model. We get the power and performance previously available only to C++ developers, with the simplicity of ADO and a better programming model than that available with either of them!
DirectoryEntries Find versus DirectorySearcher
First-time SDS users tend to stumble upon a method called Find on the DirectoryEntries collection class. One might wonder what the difference is between this method and the FindAll and FindOne methods on DirectorySearcher. The main difference is that the DirectoryEntries.Find method actually wraps the IADsContainer.GetObject method. It takes only the relative distinguished name (RDN), and optionally, the class of the object to find, as arguments. It will also search only the immediate container (no children containers) and will throw an exception that must be handled if the object is not found. As such, its use is fairly limited.
DirectorySearcher supports the full gamut of search features and does not suffer from these limitations. It is especially nice that it will not throw an error if no results are found! We tend to stick to DirectorySearcher for finding objects and use DirectoryEntries for the operations that actually require it, such as creating and deleting objects.
Part I: Fundamentals
Introduction to LDAP and Active Directory
Introduction to .NET Directory Services Programming
Binding and CRUD Operations with DirectoryEntry
Searching with the DirectorySearcher
Advanced LDAP Searches
Reading and Writing LDAP Attributes
Active Directory and ADAM Schema
Security in Directory Services Programming
Introduction to the ActiveDirectory Namespace
Part II: Practical Applications
Part III: Appendixes
Appendix A. Three Approaches to COM Interop with ADSI
Appendix B. LDAP Tools for Programmers
Appendix C. Troubleshooting and Help