Why a query with PowerShell in Active Directory should be built very precisely!

%3CLINGO-SUB%20id%3D%22lingo-sub-3042679%22%20slang%3D%22en-US%22%3EWhy%20a%20query%20with%20PowerShell%20in%20Active%20Directory%20should%20be%20built%20very%20precisely!%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-3042679%22%20slang%3D%22en-US%22%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EDear%20Microsoft%20and%20PowerShell%20Friends%2C%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20this%20article%20I%20will%20describe%20why%20it%20is%20important%20to%20create%20a%20query%20with%20PowerShell%20in%20Active%20Directory%20as%20precisely%20as%20possible.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EImagine%20you%20have%20to%20find%20all%20accounts%20where%20the%20value%20%22Luzern%22%20is%20entered%20in%20the%20attribute%20%22City%22.%20This%20may%20not%20be%20a%20challenge%20at%20first%20sight.%20Let's%20take%20it%20step%20by%20step.%20Let's%20first%20see%20how%20many%20user%20accounts%20there%20are%20in%20my%20demo%20Active%20Directory.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E(The%20hashtags%20are%20comments)%3A%3C%2FP%3E%0A%3CP%3E%23How%20many%20AD%20object%20are%20there%3F%3CBR%20%2F%3E%3CSTRONG%3EGet-ADUser%20-Filter%20*%20%7C%20Measure-Object%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22_AD_01.JPG%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F335124i80B27FE7EB23AACA%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22_AD_01.JPG%22%20alt%3D%22_AD_01.JPG%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThese%20are%20really%20very%20few%20accounts.%20After%20all%2C%20it%20is%20only%20a%20test%20environment.%20But%20imagine%20if%20there%20were%201000%2C%2010%2C000%20or%2050%2C000%20accounts.%20Does%20that%20make%20a%20difference%3F%20YES!%20This%20can%20have%20a%20bad%20effect%20on%20the%20performance%20of%20the%20server%20(domain%20controller)%20during%20a%20query.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENow%20let's%20find%20those%20accounts%20which%20have%20the%20value%20%22Luzern%22%20in%20the%20attribute%20%22City%22%20and%20we%20will%20measure%20the%20query%20time.%20I%20will%20first%20be%20very%20general%20with%20the%20queries%20and%20then%20become%20more%20and%20more%20precise.%20Let's%20rock!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%23A%20first%20search%3CBR%20%2F%3E%3CSTRONG%3EGet-ADUser%20-Filter%20*%20-Properties%20*%20%7C%20Where-Object%20%7B%24PSItem.city%20-eq%20%22Luzern%22%7D%20%7C%20%3C%2FSTRONG%3E%3CBR%20%2F%3E%3CSTRONG%3ESelect-Object%20Name%2CDepartment%2CTitle%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22_AD_02.JPG%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F335125i128CC21C67C9F50B%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22_AD_02.JPG%22%20alt%3D%22_AD_02.JPG%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWe%20get%20the%20result%20means%20we%20see%20the%20accounts%20we%20were%20looking%20for.%20But%20how%20long%20did%20this%20query%20take%3F%20Let%20us%20measure%20this.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%23How%20long%20does%20this%20search%20take%3F%20We%20focus%20on%20the%20TotalSeconds%3CBR%20%2F%3E%3CSTRONG%3EMeasure-Command%20%7BGet-ADUser%20-Filter%20*%20-Properties%20*%20%7C%20%3C%2FSTRONG%3E%3CBR%20%2F%3E%3CSTRONG%3EWhere-Object%20%7B%24PSItem.city%20-eq%20%22Luzern%22%7D%20%7C%20Select-Object%20Name%2CDepartment%2CTitle%7D%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22_AD_03.JPG%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F335126iE19E0A8CB663E681%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22_AD_03.JPG%22%20alt%3D%22_AD_03.JPG%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThis%20query%20took%20(TotalSeconds)%200.0442281%20seconds.%20We%20do%20the%20exact%20same%20query%20again%20but%20we%20now%20focus%20directly%20on%20the%20%22TotalSeconds%22.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%23So%20we%20get%20the%20TotalSeconds%20right%20away%3CBR%20%2F%3E%3CSTRONG%3E(Measure-Command%20%7BGet-ADUser%20-Filter%20*%20-Properties%20*%20%7C%20Where-Object%20%7B%24PSItem.city%20-eq%20%22Luzern%22%7D%20%7C%26nbsp%3B%3C%2FSTRONG%3E%3CSTRONG%3ESelect-Object%20Name%2CDepartment%2CTitle%7D).TotalSeconds%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22_AD_04.JPG%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F335127i9C79F485994BE703%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22_AD_04.JPG%22%20alt%3D%22_AD_04.JPG%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThe%20query%20time%20is%20about%20the%20same.%20That%20fits.%20But%20now%20we%20will%20optimize%20the%20query%20a%20bit%20and%20then%20measure%20the%20time%20again.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%23Now%20we%20adjust%20our%20search%20and%20measure%20the%20time%20again%3CBR%20%2F%3E%3CSTRONG%3E(Measure-Command%20%7BGet-ADUser%20-Filter%20%7Bcity%20-eq%20%22Luzern%22%7D%20-Properties%20*%20%7C%20%3C%2FSTRONG%3E%3CBR%20%2F%3E%3CSTRONG%3ESelect-Object%20Name%2CDepartment%2CTitle%7D).TotalSeconds%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22_AD_05.JPG%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F335128i3057505E4040F89B%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22_AD_05.JPG%22%20alt%3D%22_AD_05.JPG%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWe%20have%20already%20been%20able%20to%20reduce%20the%20query%20time!%20Now%20let%20us%20make%20the%20query%20even%20more%20precise%20and%20we%20will%20measure%20again.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%23And%20again%20an%20adjustment%20of%20the%20search%20and%20measure%20again%3CBR%20%2F%3E%3CSTRONG%3E(Measure-Command%20%7BGet-ADUser%20-Filter%20%7Bcity%20-eq%20%22Luzern%22%7D%20-Properties%20Name%2CDepartment%2CTitle%20%7C%26nbsp%3B%3C%2FSTRONG%3E%3CSTRONG%3ESelect-Object%20Name%2CDepartment%2CTitle%7D).TotalSeconds%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22_AD_06.JPG%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F335129iB19313FFFBC1F49F%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22_AD_06.JPG%22%20alt%3D%22_AD_06.JPG%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAwesome.%20We%20achieved%20a%20query%20time%20of%200.0084811%20(instead%20of%200.0442281)%20seconds.%20Super!%20Don't%20forget%20we%20are%20testing%20in%20a%20very%20small%20environment%20here.%20What%20would%20the%20times%20be%20like%20if%20the%20Active%20Directory%20had%20thousands%20of%20accounts%3F%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EClearly%2C%20that%20was%20not%20super%20spectacular%20or%20fancy.%20But%20I%20still%20wanted%20to%20share%20my%20experience%20with%20you.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20this%20article%20I%20wanted%20to%20show%20how%20important%20it%20is%20to%20create%20the%20PowerShell%20queries%20as%20precisely%20as%20possible.%20Thank%20you%20for%20taking%20the%20time%20to%20read%20this%20article.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EKind%20regards%2C%20Tom%20Wechsler%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EP.S.%20All%20scripts%20(%23PowerShell%2C%20Azure%20CLI%2C%20%23Terraform%2C%20%23ARM)%20that%20I%20use%20can%20be%20found%20on%20github!%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Ftomwechsler%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2Ftomwechsler%3C%2FA%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-3042679%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EWindows%20PowerShell%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EWindows%20Server%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
MVP

 

Dear Microsoft and PowerShell Friends,

 

In this article I will describe why it is important to create a query with PowerShell in Active Directory as precisely as possible.

 

Imagine you have to find all accounts where the value "Luzern" is entered in the attribute "City". This may not be a challenge at first sight. Let's take it step by step. Let's first see how many user accounts there are in my demo Active Directory.

 

(The hashtags are comments):

#How many AD object are there?
Get-ADUser -Filter * | Measure-Object

_AD_01.JPG

 

These are really very few accounts. After all, it is only a test environment. But imagine if there were 1000, 10,000 or 50,000 accounts. Does that make a difference? YES! This can have a bad effect on the performance of the server (domain controller) during a query.

 

Now let's find those accounts which have the value "Luzern" in the attribute "City" and we will measure the query time. I will first be very general with the queries and then become more and more precise. Let's rock!

 

#A first search
Get-ADUser -Filter * -Properties * | Where-Object {$PSItem.city -eq "Luzern"} |
Select-Object Name,Department,Title

_AD_02.JPG

 

We get the result means we see the accounts we were looking for. But how long did this query take? Let us measure this.

 

#How long does this search take? We focus on the TotalSeconds
Measure-Command {Get-ADUser -Filter * -Properties * |
Where-Object {$PSItem.city -eq "Luzern"} | Select-Object Name,Department,Title}

_AD_03.JPG

 

This query took (TotalSeconds) 0.0442281 seconds. We do the exact same query again but we now focus directly on the "TotalSeconds".

 

#So we get the TotalSeconds right away
(Measure-Command {Get-ADUser -Filter * -Properties * | Where-Object {$PSItem.city -eq "Luzern"} | Select-Object Name,Department,Title}).TotalSeconds

_AD_04.JPG

 

The query time is about the same. That fits. But now we will optimize the query a bit and then measure the time again.

 

#Now we adjust our search and measure the time again
(Measure-Command {Get-ADUser -Filter {city -eq "Luzern"} -Properties * |
Select-Object Name,Department,Title}).TotalSeconds

_AD_05.JPG

 

We have already been able to reduce the query time! Now let us make the query even more precise and we will measure again.

 

#And again an adjustment of the search and measure again
(Measure-Command {Get-ADUser -Filter {city -eq "Luzern"} -Properties Name,Department,Title | Select-Object Name,Department,Title}).TotalSeconds

_AD_06.JPG

 

Awesome. We achieved a query time of 0.0084811 (instead of 0.0442281) seconds. Super! Don't forget we are testing in a very small environment here. What would the times be like if the Active Directory had thousands of accounts?

 

Clearly, that was not super spectacular or fancy. But I still wanted to share my experience with you.

 

In this article I wanted to show how important it is to create the PowerShell queries as precisely as possible. Thank you for taking the time to read this article.

 

Kind regards, Tom Wechsler

 

P.S. All scripts (#PowerShell, Azure CLI, #Terraform, #ARM) that I use can be found on github! https://github.com/tomwechsler

0 Replies