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

Learn How to PowerShell Like a Pro

Guy Leech
September 23, 2022

Learn How to PowerShell Like a Pro

See some tips from a professional PowerShell coder on how to write code which is robust, reusable, readable and right in order to make your life, and that of your co-workers/customers, easier.

Guy Leech

September 23, 2022
Tweet

More Decks by Guy Leech

Other Decks in Technology

Transcript

  1. WRITING
    ROBUST
    POWERSHELL
    CODE
    Guy Leech
    @guyrleech

    View Slide

  2. whoami /user
    • 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 (Comp Sci)
    • Started with Windows (NT 3.51) in 1995 via Citrix (installed via 35 floppies!)
    • Invented & wrote what is now Ivanti Application Control security product (was AppSense)
    • Freelance consultant writing PowerShell for software vendors like ControlUp, Flexxible IT,
    PolicyPak
    • Microsoft MVP, Citrix CTP, VMware vExpert, Parallels VIPP
    • Master of Dad jokes
    @guyrleech
    Slide 1 of 0xdead

    View Slide

  3. Why Write Robust Code?
    • Less comeback
    • Fewer problems to rectify afterwards
    • Higher successful outcomes
    • Why not? Do it as you code, not "later" so becomes habit
    • Reputation
    • "Write it once, write it right"
    @guyrleech

    View Slide

  4. Questions about Error Handling
    • Does it benefit the user if the error is reported?
    • Is there anything that can be done to avoid/predict the error?
    • Is there anything that can be done to fix the error?
    • Is it a fatal error or can we continue (change to warning)?
    • Does the error message make sense to mere mortals?
    • Change the error text to display remedial action, KB references, etc
    • Can the user actually deal with raw errors?
    @guyrleech

    View Slide

  5. Errors
    • Check for errors even if not obvious that has errored
    • Be Consistent
    • Expected errors (e.g. create folder when already exists)
    • If you explicitly ignore/hide an error have a comment saying why
    • Beware modules/cmdlets that output error to stdout
    • Or don't output errors at all or return status (and use Write-Host)
    • Zero can be error ($false) or success (ERROR_SUCCESS in Windows APIs)
    @guyrleech

    View Slide

  6. Checking for Errors
    • Validate return values
    • Abort, abort, abort!
    • $?
    • $error
    • Array
    • $error.Clear()
    • -ErrorVariable (works with –ErrorAction SilentlyContinue)
    • -PassThru
    • Extra checks, e.g. if folder creation, check folder created
    @guyrleech

    View Slide

  7. Exceptions
    • Designed to simplify error checking
    • Compromise – 1x try catch around whole code vs try catch around everything
    • Can be ignored but is that wise?
    • Use $_ to examine exception in catch block
    • Catch specific exceptions if you are going to deal with them differently
    • catch [System.Management.Automation.DriveNotFoundException]
    • $_.Exception.gettype().FullName
    • Try catch finally – finally useful for tidy up like removing temp files
    • Beware error message containing "At line:1 char:1"
    @guyrleech

    View Slide

  8. Variables: Strong Typing & Initialisation
    • Declaring type helps catch static errors & helps intellisense
    • Script variables and parameters
    • Get type name from a variable via GetType().FullName
    • Declare and initialise to known value, typically $null or -1
    • De-initialisation
    • Call Dispose(), Close() etc as relevant (Get-Member)
    • Set to $null when finished or even remove variable
    @guyrleech

    View Slide

  9. Additionally #1
    • Comments (and update/delete them)
    • Meaningful variable names $i
    • $ErrorActionPreference = 'SilentlyContinue' Never!
    • But do use it on individual cmdlets as necessary/appropriate
    • $null and zero are different – which do you need to check for? -not
    • Check property exists before referencing if may be missing
    • If($null -ne $guysobject.PSObject.Properties[ 'SomeProperty' ] ) {
    • Invoke-SomeFunction –InputObject $guysobject.SomeProperty }
    • Use named parameters with full name, not positional or abbreviated
    • Sanity checks parameters as much as possible & give meaningful errors
    • No aliases in scripts, only use them interactively (or for tweets)
    @guyrleech

    View Slide

  10. Additionally #2
    • Check size of array before indexing in to it
    • [-1] for last item
    • Check not $null before using Count property
    • Watch for array flattening where single item not returned as array
    • Wrap in @()
    • Opposite – get an array when expecting single item
    • Select –First/-Last
    • -is [array]
    • Use –as instead of [type] cast
    • TryParse & TryParseExact methods
    • [string]::IsNullOrEmpty()
    • Use extra parentheses if makes it easier to read/understand
    • If you are copying & pasting the same chunk of code, you should use functions
    @guyrleech

    View Slide

  11. Testing
    • Different PowerShell versions (#requires –version)
    • Different environments
    • Different operating systems
    • Admin vs non-admin (#requires -runasadministrator)
    • Edge cases (what if the user has (stupidly) done …)
    • Different users
    • "What If" code walk throughs
    @guyrleech

    View Slide

  12. Aids
    • Set-StrictMode
    • PSScriptAnalyzer
    • ISE Steroids
    • Pester
    • Code review
    • Other people's code
    @guyrleech

    View Slide

  13. References
    • Guy’s In Person PowerShell Workshops
    • https://powershellexplained.com/2017-04-10-Powershell-exceptions-everything-
    you-ever-wanted-to-know
    • https://docs.microsoft.com/en-
    us/powershell/module/microsoft.powershell.core/about/about_functions_advance
    d_parameters?view=powershell-5.1
    • https://github.com/PowerShell/PSScriptAnalyzer
    • https://powershell.one/isesteroids/quickstart/overview
    • https://github.com/guyrleech
    @guyrleech

    View Slide

  14. Questions
    @guyrleech

    View Slide