When I am writing PowerShell scripts, one thing that is always in my mind: How long will it take to run this script and what can I do to reduce the run time.

While optimizing the code itself is not the scope of this article, what I am going to write may help you determine how long your script, function or code sections takes to run.

Insert the following at start of the section of code you want to check:

# Get Start Time
$startDTM = (Get-Date)

Insert the following at the end of the section of code you want to check:

# Get End Time
$endDTM = (Get-Date)
 
# Echo Time elapsed
"Elapsed Time: $(($endDTM-$startDTM).totalseconds) seconds"

Here is an example of my code optimization:

BEFORE (Run Time 40.4 seconds):

filter GetMailboxCount{
$Server = $_
 
$strFilter = "(&(&(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(msExchHomeServerName=$Server)) ))))"
 
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
 
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
$objSearcher.SearchScope = "Subtree"
 
$colResults = $objSearcher.FindAll()
$colCount = ($colResults | Measure-Object | %{$_.Count})
"$Server,$colCount"
 
}

AFTER (Run Time 4.53 seconds):

filter GetMailboxCount{
$Server = $_
 
$strFilter = "(&(&(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(msExchHomeServerName=$Server)) ))))"
 
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
 
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
$objSearcher.SearchScope = "Subtree"
 
$colProplist = "name"
$retval = $colProplist | foreach {$objSearcher.PropertiesToLoad.Add($_)}
 
$colResults = $objSearcher.FindAll()
$colCount = ($colResults | Measure-Object | %{$_.Count})
"$Server,$colCount"
 
}

As you will see the “name” property is irrelevant to my code but by querying on indexed attribute and limiting scope of the query, I was able to improve run time ten folds. Now that is huge time savings when you have to run this code in a loop across all of your servers!