Getting better performance when searching for accounts
active-directory, powershell
Solution
I'd start by doing one bulk query of AD, and building a hash table (Key = EmployeeID, Value = DN), and then work from that.
$hash = @{}
Get-ADUser -Properties EmployeeID -Filter * |
foreach {$hash[$_.EmployeeID] = $_.DistinguishedName}
$csv = Import-CSV -Path $someFile
Foreach($line in $csv){
$DoesAccountExist = [bool]($hash[$line.employeeid])
}
$hash[$line.employeeid] will return the DN of the user that belongs to that employeeid if it's in the table.
Problem
I'm trying to find an efficient way to query large amounts of user accounts in ActiveDirectory, and I'm having a bit of an issue. I have a script that goes through a file exported from another employee management program grabbing employeeIDs, which I then search for in ActiveDirectory. Every user account has an associated employeeID, and I use whether or not a certain ID is found in A/D to show whether an account should be created or deleted (if in file but not A/D, create; if in A/D but not file, delete). My problem is that I cannot find an efficient way to do this. My old method was to search for every employeeID one at a time with Get-ADUser, but this was very slow. I've also tried pulling down all the non-system accounts, and then using Where-Object on the list to filter out the account that matches. This also gets very slow with large amounts of accounts because Where-Object is checking every single account in my array of accounts. I think there must be a faster way to do this, since I'm able to slam a -contains on the attribute I'm trying to match and get a response for every ID within a minute or so, versus the 20 it takes to run a where-object. Any advice? Some notes: I have already preprocessed the IDs coming from the file and the IDs in ActiveDirectory to make sure there are no duplicates, so only getting the first result is fine. Old Method (simplified with processing code taken out): ``` $csv = Import-CSV -Path $someFile Foreach($line in $csv){ $DoesAccountExist = Get-Aduser -filter {employeeID -eq $line.employeeID} } ``` Working in memory method: ``` $csv = Import-CSV -Path $someFile $Users = Get-Aduser -filter * $NonSystemUsers = $users | Where-Object {$_.employeeID -match $employeeIDPattern} #This is the part that is slow foreach($line in $csv){ $DoesAccountExist = $NonSystemUsers | Where-Object {$_.employeeID -eq $line.employeeID} } ```