Discovering the Active Directory Searcher with PowerShell

Create New Active Directory Users with Excel and PowerShell
Over the last several weeks, I have been demonstrating how you can manage Active Directory with PowerShell. I have been doing so without relying on the Active Directory module that ships as part of Remote Server Administration Tools (RSAT). There is nothing inherently wrong or bad about using Get-ADUser but there may be situations where you do not have that toolset handy. One topic I still need to address is searching. For the sake of demonstration, all of my commands are being run on a domain-joined Windows 10 desktop. It is under an account that has domain admin privileges. For simple searching, you should be able to use a normal user account. You may do this differently if you have messed around with default permissions.
 

 
To begin, we need a searcher object:

$searcher = New-Object system.DirectoryServices.DirectorySearcher

You will end up with an object like this:

AD Searcher Object (Image Credit: Jeff Hicks)
AD Searcher Object (Image Credit: Jeff Hicks)

The key property is the filter. This tells the searcher what to find. Unfortunately, this is also the trickiest part because you need to use an LDAP query string. I will give you some examples to get started. Currently the filter, (Objectclass=*), will return every single object in Active Directory. You probably do not need this function.
Instead, let’s find my user account:

$searcher.filter = "samaccountname=jeff"

How do we use this? One step you can take is to use Get-Member. You can see the different methods that are available:

Getting Searcher Methods (Image Credit: Jeff Hicks)
Getting Searcher Methods (Image Credit: Jeff Hicks)

I went ahead and highlighted the relevant methods. The FindOne() method will execute the search. It will also stop after the first matching result is discovered. FindAll() will search the entire Active Directory for objects that match the filter. Since there should be only a single object with a samaccountname of Jeff, the former should be sufficient:
Finding a single AD account (Image Credit: Jeff Hicks)
Finding a Single AD Account (Image Credit: Jeff Hicks)

The Path property is the LDAP path to the object. The properties are a subset of the complete object:
Search Result Properties (Image Credit: Jeff Hicks)
Search Result Properties (Image Credit: Jeff Hicks)

You can verify that this is not the complete object by piping to Get-Member. You will see that $me is a System.DirectoryServices.SearchResult object. The tricky part is getting property values out of this collection.

Because Properties is already a hash table, you could use quick and dirty code:
Selecting Result Properties (Image Credit: Jeff Hicks)
Selecting Result Properties (Image Credit: Jeff Hicks)

It is not pretty but it gets the job done. For something a bit neater, we need to resort to a little scripting:

$me.properties.PropertyNames | foreach -begin {
  $h=@{}
} -process {
$value = $me.Properties.item($_)
if ($value.count -eq 1) {
  $value = $value[0]
}
$h.add($_,$value)
} -end {
  new-object psobject -property $h
}

Converting to an object (Image Credit: Jeff Hicks)
Converting to an Object (Image Credit: Jeff Hicks)

If you know in advance what properties you want, you could take this approach:

$props = "Name","Title","Department","Samaccountname","DistinguishedName","DirectReports"
$h = @{}
foreach ($p in $props) {
$value = $me.Properties.item($p)
if ($value.count -eq 1) {
  $value = $value[0]
}
  $h.add($p,$value)
}
new-object psobject -property $

Displaying Specific Properties (Image Credit: Jeff Hicks)
Displaying Specific Properties (Image Credit: Jeff Hicks)


You can probably tell that if you want to use the directory searcher, you will need to create some tooling around it. There is much more we need to explore first. We will pick up here next time. We will also look at how to search for multiple objects and some LDAP filtering tips.