(in BASIC) ▪ Unix developer in C/C++ for 6 years after graduation from University of Manchester in 1988 ▪ Started with Windows (NT 3.51) in 1995 via Citrix ▪ Invented & wrote what is now Ivanti Application Control security product ▪ Freelance consultant writing PowerShell for software vendors like ControlUp, Flexxible IT, Avanite ▪ Current Microsoft MVP, Citrix CTP, VMware vExpert, Parallels VIPP @guyrleech
functionality ▪ Does taking 15 minutes instead of 5 really matter? ▪ How much time/money will it take to make it significantly faster? ▪ Do not run scripts on key infrastructure servers use a jump box ▪ Think about performance when writing code ▪ Expressions evaluated left to right in an if statement ▪ Filter as far left as possible @guyrleech
consider the impact of the script on your environment ▪ Reduce the process' base priority ▪ (Get-Process –id $pid).PriorityClass = 'BelowNormal' ▪ Do you need to repeat the looping? ▪ Do you need Write-Verbose, Write-Progress etc on every iteration? ▪ .Where (collections) versus Where-Object ▪ ForEach versus ForEach-Object versus .ForEach (collections) ▪ . { Process { } } @guyrleech
existing object ▪ Can get slow for large items ▪ It is ok for hashtables ▪ Arrays ▪ Assign results to an array rather than adding to it within the loop ▪ Wrap in @( ) to avoid PowerShell's "helpful" array flattening "feature" ▪ Instead use System.Collections.Generic.List[object] which has Add/Remove methods ▪ Iterate backwards if calling Remove() ▪ Do not use System.Collections.ArrayList ▪ Strings ▪ $oldstring = $oldstring + $newstring ▪ $oldstring = "$oldstring$newstring" ▪ $oldstring = -join ( $oldstring , $newstring ) @guyrleech
up individually/once? ▪ Get-ADUser ▪ Get-BrokerMachine ▪ But what is the memory overhead? ▪ Be selective what properties are cached ▪ Trim own working set ▪ Destroy unused data/variables ▪ [gc]::Collect() ▪ Hashtable or array ? ▪ Unique key ? ▪ Hashtable of arrays ▪ Sort ? ▪ Most likely to be accessed near the start ▪ Binary search via index ? ▪ Number of elements ▪ .Where() versus Where-Object ▪ .Where takes optional count x, for where-object pipe through Select-Object –First x ▪ [System.Management.Automation.WhereOperatorSelectionMode] @guyrleech
command? ▪ Always use Import-Module in scripts in case of new/non-persistent profile ▪ In a loop, can add time locating command ▪ Could module qualify (also helps avoid ambiguity/incorrect cmdlet use) ▪ VMware.VimAutomation.Core\Get-VM versus Hyper-V\Get-VM ▪ Get-Command ▪ Call with . or & @guyrleech
▪ Pwsh 7.x has ForEach-Object -Parallel ▪ Windows PowerShell has Invoke-Command –ComputerName ▪ Can use localhost ▪ Needs remoting configured ▪ Runspaces ▪ Not as scary as you might think ▪ Take some working code (give credit) and modify @guyrleech