How Do You Select Collection Objects by Value?

by dunagh at 2013-01-16 15:04:22

I have to run a script against a lot of users in Active Directory. I can lookup each user one at a time, as I am doing now, but had the idea that it may be faster to only query the AD once and then do a lookup on the local copy of the AD users (a little over 7000). My query would be such:

$ADUsers = Get-ADUser -Filter {Enabled -eq $true} -Properties Name,SamAccountName,SID,GivenName,Initials,Surname
So my question is, how would I lookup "Sally Johnston" in $ADUsers?

Thanks,
by nohandle at 2013-01-16 23:43:12
I don’t think doing local copy of ad is a good idea or it would be faster than querying it (unless you query the 7000 objects like 50 000 times). Also you have to be sure nothing changed in the global AD while you were playing with your local copy.
To look up someone just pipe the adUsers to apropriate where-object.

Just out of curiosity how do you query the AD now? Do you filter the results by ldap filter or by where-object?
by RichardSiddaway at 2013-01-17 00:04:34
I agree with nohandle. Its nearly always better to go back to the original data. How often were you planning on refreshing the offline data? Get-ADUser is reasonably fast and if you can supply an OU that can make things much faster.

In this case with only 7000 users I’d go back to AD. If you are worried about time to execute then run it as a background job overnight or split the script into a few batches
by nohandle at 2013-01-17 01:03:11
The important thing to speed up the process is to query for as specific set of objects as you can. That is why I am interested in the technique you use to retrieve the users. People tend to ask for all users and then filter them locally using the where-object which is considerably slower than asking for the specific object using LDAP filter.
by dunagh at 2013-01-17 08:31:12
I potentially run this query against 3500 computers, where I query the computer description field which is supposed to contain the user assigned to the system. From there, I parse the user name and do a lookup on the username with the following query, which may return more than one user. This is how I pull my ad query:

$ADUser = Get-ADUser -Filter { (Surname -eq $userLN) -and (GivenName -like $userFN) -and (GivenName -notlike "*Test") -and (Enabled -eq $true) } -Properties *

I can probably filter down the properties but I was being lazy when I wrote the query :-). The script runs whenever we want to refresh the data and after that, all AD information is destroyed. As it stands right now, it takes my script almost an hour, if not longer, to do the initial gathering of data. This is not just an issue of hitting the AD several times but also I am attempting to connect to a remote system to validate the user who is actually logged in to the computer. This can be slow because our users are spread out across our state, some on really slow connections.

I am not convinced that caching a local copy of the AD will create an extreme performance boost, but if I can cut a few seconds here or there per computer I’ll take it.
by nohandle at 2013-01-17 08:40:28
[quote="dunagh"]I potentially run this query against 3500 computers, where I query the computer description field which is supposed to contain the user assigned to the system.[/quote]
[quote="dunagh"] As it stands right now, it takes my script almost an hour, if not longer, to do the initial gathering of data. This is not just an issue of hitting the AD several times but also I am attempting to connect to a remote system to validate the user who is actually logged in to the computer. This can be slow because our users are spread out across our state, some on really slow connections.[/quote]As I read it you first get the data from AD then you reach to the computer to get the user logged on, (some of the computers are probably down) and then you query the AD again?
Connecting to the computers seems like a bottleneck here.
Do you do it one computer after another or do you use jobs to do it in parallel?
by dunagh at 2013-01-17 09:58:38
Yes, you read that correctly; that is the gist of what I am doing. I know connecting to the computers is the bottlenck (indeed, many of the systems are either down, or I get unauthorized access errors). That is why I was hopping to speed up the script by a second or two per computer. Thinking about it, I should probably attempt to connect to the computer first and then contact the AD when I know I have access to this system.

Sadly I have not learned how to use jobs yet but would love to thread this script to enable it to run faster. That will be the next phase of my powershell quest.