I’m pretty sure this is covered in some post already on the world wide interwebs but since it took me some time to figure this one out I’m putting it up here.
For those of you who write code that talks to Active Directory (using the DirectorySearcher object in this case), this is a nice little detail.
The code I was working on validates a computername supplied by the user. Since I already had code that can find a user via their SAMAccountName, I decided to go down that same route.
Here is the code for a DirectorySearcher that finds users by their SAMAccountName:
var searcher = new DirectorySearcher(rootEntry)
{
SearchScope = SearchScope.Subtree,
Filter = string.Format("(&(sAMAccountName={0})(objectClass=user))", dHelper.EscapeForLdap(sAMAccountName))
};
So my guess was:
var searcher = new DirectorySearcher(rootEntry)
{
SearchScope = SearchScope.Subtree,
Filter = string.Format("(&(sAMAccountName={0})(objectClass=computer))",
AdHelper.EscapeForLdap(computerSAMAccountName))
};
The code ran fine, but it never found any computers even though they existed in Active Directory. What’s up with that?
After some digging around I came across this tiny little detail using ADSI Edit:
So there is a dollar ($) sign appended there? Hmm, creating a new computer also adds the dollar sign to the end of the supplied name. Using this info I continued my search and ended up here:
http://msdn.microsoft.com/en-us/library/aa370254(v=vs.85).aspx
Aha!
A computer account name always has a trailing dollar sign ($). Any functions used to manage computer accounts must build the computer name such that the last character of the computer account name is a dollar sign ($). For interdomain trust, the account name is TrustingDomainName$.
Changing the Filter to this:
Filter = string.Format("(&(sAMAccountName={0}$)(objectClass=computer))", AdHelper.EscapeForLdap(computerSAMAccountName))
Solves my filtering problem and the method is now returning the correct results.