Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PowerShell Performance Pointers

Guy Leech
November 10, 2021

PowerShell Performance Pointers

Hints and tips to make PowerShell code perform better.

Presented at the PowerShell Berlin User Group, 10th November 2021

Guy Leech

November 10, 2021
Tweet

More Decks by Guy Leech

Other Decks in Technology

Transcript

  1. Guy Leech
    @guyrleech

    View Slide

  2. ▪ Wrote my first code (on Commodore PET) in 1980 (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

    View Slide

  3. ▪ Not usually
    ▪ Nowhere near as important as (correct) 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

    View Slide

  4. ▪ Measure-Command
    ▪ Once is not enough
    ▪ Watch for file system caching and other optimisations
    ▪ Get-Date
    ▪ [Diagnostics.Stopwatch]
    ▪ Guy's clock/stopwatch
    ▪ PSProfiler
    @guyrleech

    View Slide

  5. ▪ Don't keep evaluating/fetching/setting the same thing
    ▪ Start-Sleep – 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

    View Slide

  6. ▪ For arrays and strings, takes a complete copy of 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

    View Slide

  7. ▪ Is it quicker to keep in memory than look 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

    View Slide

  8. ▪ How long does it take PowerShell to find a 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

    View Slide

  9. ▪ Can the tasks be split into separate, unrelated, activities?
    ▪ 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

    View Slide

  10. ▪ https://gitgub.com/guyrleech
    ▪ https://github.com/IISResetMe/PSProfiler
    ▪ https://fatherjack.github.io/articles/Where
    ▪ https://4sysops.com/archives/understanding-powershell-begin-process-and-end-blocks/
    @guyrleech

    View Slide

  11. @guyrleech

    View Slide