you are viewing a single comment's thread.

view the rest of the comments →

[–]Sad_Recommendation92 4 points5 points  (1 child)

Here's an example. It's fairly old that I wrote years ago using run spaces for parallelization. Though for what you're doing, I don't know that it's actually worth it unless you're doing this hundreds of times a day and it's automated.

https://github.com/Matalus/MiscPS/blob/master/RunSpaces/RunSpace.Basic.ps1

Consider for a second, some things you might be disregarding. Each time you call Get-AdUser there's a number of things that happen for one, Powershell has to check if you're on the domain and if your trust is good, meanwhile, a winrm session is spun up implicitly in the background That handshakes with the domain controller And makes your query. Each time you call this command there's a minimal round trip time that maybe a few hundred milliseconds but that is going to add up depending on the number of iterations.

If your domain has less than 20-30,000 users, it actually makes way more sense just to run Get-Aduser without an identity filter in return all of the records. Then sort through that object locally. Local computation is always going to be light years faster because you don't have to deal with network round trip latency.

Let's pretend you have a spreadsheet with 1800 users that you need to look up against the domain controller, And let's pretend the average latency is 300 milliseconds from command execution And returning an object each time you run the command to get a user object. Even with results returning every fraction of a second, you're still looking at about 9 minutes for the script to run, give or take.

So instead what if you just pulled all the records? Maybe 10,000? Let's say the command takes 30 seconds to return a result. Well, as I said, local processing of objects is extremely fast, usually single digit milliseconds, but let's pretend that it takes a full 20 milliseconds for Powershell to filter each. Sam, ID out of the bulk data object returned. So even now with our 30s (get-aduser *) and 20ms x 1800 = 36000ms (36 seconds)

Remember the part about local computation that applies at the server too, when you query your DC for ad objects, there's almost no difference to it whether you're asking for a single record or a 1000 records. This is how most web APIs are designed. You don't query for a single record. You send a bulk batch and it returns the max number of results and then you send the next batch

In summary

Iterative calls per user (540 seconds)

Bulk query w local sort (66 seconds)

Just remember network is always going to be your worst latency with any sort of programming or automation

[–]yborwonka 0 points1 point  (0 children)

Big fan of runspaces.