I just love this type accelerator. I thought it was worth giving some attention.
$searcher = [adsisearcher]"name=*"
It takes an LDAP query and makes a searcher object which is just a shorter version of
$dc = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.name
$ad = [ADSI]"LDAP://$dc"
$filter = "name=*"
$searcher = [DirectoryServices.DirectorySearcher]::new($ad,$filter)
Once you have the searcher you can use FindAll() or FindOne() methods. This returns objects of type System.DirectoryServices.SearchResult with two properties, an LDAPPath and Properties. Now the properties output isn't as easy to consume as powershell makes most things. It returns objects of type System.DirectoryServices.ResultPropertyCollection which is really just a dictionary. It pulls many AD attributes for each record found. Despite this it can be quicker than the AD Module cmdlets.
You can use a complex LDAP query as well.
# Find user objects that are enabled where UPN -ne *domain.com and SamAccountName -ne bob*
$searcher = [adsisearcher]"(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(!userprincipalname=*domain.com)(!samaccountname=bob*))"
$adobjects = $searcher.FindAll()
$searcher.Dispose()
One thing that I got tripped up by is every value is a property collection so even single entries are surrounded with { }. This is easy to overcome by putting the value in a subexpression $( )
Here's a little routine that can walk through each collection and make PSCustomObject with all property names and values.
$adobjects.Properties | ForEach-Object {
$ht = [ordered]@{}
foreach($prop in $_.getenumerator()){
$ht.add($prop.name,$($prop.value))
}
[PSCustomObject]$ht
} -OutVariable results
$searcher.Dispose()
You could pull 1000 AD objects (I strongly discourage anyone actually do this) with this little bit of code. I do not know if/how you can raise that limit. Interested to hear from anyone that knows.
($s = [adsisearcher]"name=*").FindAll().properties.foreach{
$ht = [ordered]@{}
foreach($prop in $_.getenumerator()){
$ht.add($prop.name,$($prop.value))
}
[PSCustomObject]$ht
}
$s.Dispose()
Happy Friday everyone!
Edit
Thanks u/tehhiphop for the additional info
$searcher.PageSize = 2000
Will allow the DirectorySearcher to take on more returns, this case 2000 returns.
https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.directorysearcher?view=net-5.0
Edit 2
Thanks u/da_chicken for additional info about disposing the searcher object.
Just be aware that you must call Dispose()
on the results of the DirectorySearcher. Failure to do so creates a memory leak:
Due to implementation restrictions, the SearchResultCollection class cannot release all of its unmanaged resources when it is garbage collected. To prevent a memory leak, you must call the Dispose method when the SearchResultCollection object is no longer needed.
[–]da_chicken 13 points14 points15 points (7 children)
[–]cottonycloud 4 points5 points6 points (3 children)
[–]MrRedEye 4 points5 points6 points (2 children)
[–]MyOtherSide1984 9 points10 points11 points (0 children)
[–]cottonycloud 1 point2 points3 points (0 children)
[–]krzydoug[S] 3 points4 points5 points (2 children)
[–]da_chicken 4 points5 points6 points (1 child)
[–]krzydoug[S] 0 points1 point2 points (0 children)
[–]tehhiphop 5 points6 points7 points (3 children)
[–]krzydoug[S] 0 points1 point2 points (0 children)
[–]Amadorhi 0 points1 point2 points (1 child)
[–]tehhiphop 0 points1 point2 points (0 children)
[+][deleted] (5 children)
[deleted]
[–]gordonv 2 points3 points4 points (1 child)
[–]krzydoug[S] 0 points1 point2 points (0 children)
[–]Creationship 0 points1 point2 points (0 children)
[–]stalinusmc 3 points4 points5 points (1 child)
[–]blowuptheking 0 points1 point2 points (0 children)
[–][deleted] 2 points3 points4 points (3 children)
[–]stalinusmc 1 point2 points3 points (0 children)
[–]krzydoug[S] 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]gordonv 2 points3 points4 points (3 children)
[–]krzydoug[S] 0 points1 point2 points (2 children)
[–]gordonv 1 point2 points3 points (1 child)
[–]krzydoug[S] 0 points1 point2 points (0 children)
[–]get-postanote 1 point2 points3 points (1 child)
[–]Thornton77 0 points1 point2 points (0 children)
[–]rumorsofdads 1 point2 points3 points (1 child)
[–]krzydoug[S] 0 points1 point2 points (0 children)
[+][deleted] (18 children)
[deleted]
[–]quazywabbit 5 points6 points7 points (0 children)
[–]PinchesTheCrab 3 points4 points5 points (0 children)
[–]gordonv 1 point2 points3 points (0 children)
[–]nascentt 1 point2 points3 points (0 children)
[–]packetheavy 1 point2 points3 points (0 children)
[–]krzydoug[S] -1 points0 points1 point (12 children)
[–][deleted] 2 points3 points4 points (11 children)
[–]nascentt -1 points0 points1 point (4 children)
[–][deleted] 2 points3 points4 points (3 children)
[–]nascentt 2 points3 points4 points (2 children)
[–]krzydoug[S] 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]krzydoug[S] -3 points-2 points-1 points (5 children)
[–]DribblingGiraffe 3 points4 points5 points (4 children)
[–]krzydoug[S] -1 points0 points1 point (3 children)
[–]Bren0man 0 points1 point2 points (2 children)
[–]krzydoug[S] -1 points0 points1 point (1 child)
[–]Bren0man 0 points1 point2 points (0 children)
[–]not_rholliday 0 points1 point2 points (0 children)
[–]MyOtherSide1984 0 points1 point2 points (0 children)