I am using [adsisearcher] to grab AD User info because it's way faster than get-aduser. I am also trying to figure out how to add it into a hashtable or dictionary using LINQ or perhaps any other alternative that is fast. For me I'm trying to get the best performance/most efficiency because long term goal is importing the data into a contact list.
Here is what I currently have, and this works well, but I'm curious if there is a quicker way to organize the data?
$Start = Get-Date $searcher=[adsisearcher]"" $searcher.Sort.PropertyName = "sn" $searcher.Filter = "(&(extensionAttribute2=customValue)(|(mobile=*)(telephonenumber=*)))" $colProplist = "givenname","extensionattribute2","initials","mobile","telephonenumber","sn","displayname","company","title","mail","department","thumbnailphoto","samaccountname" foreach ($i in $colPropList){$searcher.PropertiesToLoad.Add($i) > $NULL } $End = Get-Date Write-Host "User info took $($Start - $End) seconds" Write-Host "" #---------------------------------------------------- Write-Host "Creating User Hashtable" $Start = Get-Date $Users=@{} $Users = $searcher.FindAll() | ForEach-Object{ New-Object -TypeName PSCustomObject -Property @{ 'FirstName' = $_.properties.givenname -join '' 'MiddleName' = $_.properties.initials -join '' 'LastName' = $_.properties.sn -join '' 'DisplayName' = $_.properties.displayname -join '' 'SamAccountName' = $_.properties.samaccountname -join '' 'Email' = $_.properties.mail -join '' 'Mobile' = $_.properties.mobile -join '' 'TelephoneNumber' = $_.properties.telephonenumber -join '' 'Title' = $_.properties.title -join '' 'Dept' = $_.properties.department -join '' 'Company' = $_.properties.company -join '' 'Photo' = $_.properties.thumbnailphoto -join '' 'ExtensionAttribute2' = $_.properties.extensionattribute2 -join '' } | Select-Object -Property FirstName, MiddleName, LastName, DisplayName, SamAccountName, Email, Mobile, TelephoneNumber, Title, Dept, Company, Photo, ExtensionAttribute2 } $End = Get-Date Write-Host "User HashTable took $($Start - $End) seconds" Write-Host "" I heard using LINQ is very quick, but I get stuck in properly using the syntax and I can't seem to find good documentation or examples of how to use it.
51 Answer
So, as in my comments, I personally don't see much room for improvement to your script. I have modified some minor things. You should test with measure-command and see if the code runs faster with a classic foreach loop or with a foreach-object loop.
I also changed the -join '' for strong typed [string], which I'm not sure, but might be faster.
To answer your question, why the -join '' is there, this is because each property is of the type ResultPropertyValueCollection
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False ResultPropertyValueCollection System.Collections.ReadOnlyCollectionBase By doing a -join '' you're converting the value of each property to a string:
PS /> ($z.samaccountname -join '').GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object PS /> ([string] $z.samaccountname).GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object But why is this important?
Well, very basically, if you attempt to export the data without converting those values to string to a Csv for example you would end up with something like this (you would see the type of each value instead):
$start = Get-Date $end = Get-Date $searcher = [adsisearcher]::new() $searcher.Sort.PropertyName = "sn" $searcher.Filter = "(&(objectcategory=person)(objectclass=user)(extensionAttribute2=*)(|(mobile=*)(telephonenumber=*)))" $colProplist = @( 'givenname', 'extensionattribute2' 'initials', 'mobile', 'telephonenumber' 'sn', 'displayname', 'company' 'title', 'mail', 'department' 'thumbnailphoto', 'samaccountname' ) $searcher.PropertiesToLoad.AddRange($colProplist) Write-Host "User info took $($Start - $End) seconds" Write-Host "" Write-Host "Creating User Hashtable" $users = foreach($user in $searcher.FindAll()) { $i = $user.properties [pscustomobject]@{ FirstName = [string] $i.givenname MiddleName = [string] $i.initials LastName = [string] $i.sn DisplayName = [string] $i.displayname SamAccountName = [string] $i.samaccountname Email = [string] $i.mail Mobile = [string] $i.mobile TelephoneNumber = [string] $i.telephonenumber Title = [string] $i.title Dept = [string] $i.department Company = [string] $i.company Photo = [string] $i.thumbnailphoto ExtensionAttribute2 = [string] $i.extensionattribute2 } } $End = Get-Date Write-Host "User HashTable took $($Start - $End) seconds" Write-Host "" 2 