Last Update: Sep 04, 2024 | Published: May 24, 2017
I hope by now that you are comfortable using the Active Directory Searcher object. If you have no idea what I am talking about, take a few minutes to get caught up on the previous articles, Discovering the Active Directory Searcher with PowerShell and Finding Groups with the Active Directory Searcher and PowerShell.
Let’s expand the scope and find multiple objects with user accounts.
$searcher = New-Object system.DirectoryServices.DirectorySearcher $searcher.SearchRoot = "LDAP://ou=employees,dc=globomantics,dc=local" $searcher.filter = "(objectclass=user)" $props = "distinguishedname","name","samaccountname","title","department","directreports", "whencreated","whenchanged","givenname","sn","userprincipalname","adspath" foreach ($item in $props) { $searcher.PropertiesToLoad.Add($item) | out-null }
I have limited my search to an OU that contains my active user accounts. I have also specified the properties I want to retrieve. Once the searcher is configured, I can find all matching objects.
Let’s look at a representative sample.
As we looked at before, it might be nice to clean this up and create an object to write to the pipeline.
foreach ($user in $all[4]) { $h = @{} foreach ($p in $props) { $value = $user.Properties.item($p) if ($value.count -eq 1) { $value = $value[0] } $h.add($p,$value) } new-object psobject -property $h }
Because the result properties are treated as collection objects, I needed to expand them. I still wanted to keep properties that were actual collections, like directreports. I tested with a single object and I could modify the loop to go through everything in $all. It makes more sense to create a function.
Function Convert-ADSearchResult { [cmdletbinding()] Param( [Parameter(Position = 0,Mandatory,ValueFromPipeline)] [ValidateNotNullorEmpty()] [System.DirectoryServices.SearchResult]$SearchResult ) Begin { Write-Verbose "Starting $($MyInvocation.MyCommand)" } Process { Write-Verbose "Processing result for $($searchResult.Path)" #create an ordered hashtable with property names alphabetized $props = $SearchResult.Properties.PropertyNames | Sort-Object $objHash = [ordered]@{} foreach ($p in $props) { $value = $searchresult.Properties.item($p) if ($value.count -eq 1) { $value = $value[0] } $objHash.add($p,$value) } new-object psobject -property $objHash } End { Write-Verbose "Ending $($MyInvocation.MyCommand)" } }
The function is designed to take pipelined input from any search result.
Now I can process everything and work with the results as necessary.
$all | Convert-ADSearchResult | Select Name,UserPrincipalName,Department,Title,When* | Out-GridView
Here is another way to do this.
But let’s say I wanted to find all users in the Finance department. That requires some special formatting in my LDAP filter.
$searcher.filter = "(&(objectclass=user)(department=finance))"
You need to enclose each filter part inside the (&) construct, which tells PowerShell to search for both of these things.
You can keep adding filter components inside the (&).
You can also use wildcards.
Once you have objects in PowerShell, you can work with them any way you want. I hope you will take some time to try these things out in your own test environment. Next time, we will look at searching for groups. We also still need to address handling very large number of search results and filtering tips. I hope you will keep checking back.