PET Computer Science degree (FWLIW) 6 years as a Unix device driver then app developer in C then C++ Started with Citrix (WinFrame) in 1995 Invented & wrote what is now Ivanti Application Control (was AppSense Application Manager) 150+ “useful” scripts on GitHub Mostly write PowerShell, and other languages, for software vendors Available for hire (hourly or daily) – code reviews, workshops, training, …
dirty, lazy code hoping you will come back to it someday – you won’t! Error handling from the get-go Don’t hard code anything Make it a parameter with a default value Or define as a variable near the top of the script Set-StrictMode –Version Latest (when developing/testing, not in script itself)
happens if … Check return codes/values $? -PassThru Try/catch (Script) Users do the stupidest things – code for it, don’t assume sanity How could this be misused by a bad actor? Will this work in another language? Nobody would be stupid enough to … yes, they would Protect credentials, secrets, etc SecureString & PSCredendtial types Azure Key Vault Is this date/time local or UTC ? Parameter validation – ValidateRange, ValidateSet, ParameterSetName, check
knows or remembers everything If they say they do they are either deluded or an idiot or both Surely I can’t be the first person to have/want to write something like this? If you use someone else’s code, give credit in your code & socials And check it isn’t accidentally/deliberately malicious (test, test, test (not in prod)) Don’t get disheartened if it doesn’t work first time or make silly mistakes Law of diminishing returns – know when to quit/seek help Throwing time at a problem is no guarantee of success – take a break
going, not once every few months Personal projects – I find them relaxing & fulfilling (I’m old & sad) But don’t save 10 minutes by spending 10 days on it – balance! Troubleshoot & administer via PowerShell not GUI, e.g. event logs Live in PowerShell
on the PS command line rocks! History (Get-History or alias h) makes rinse & repeat easy Ctrl r to search history (requires persistent user profile) F2 toggles in line/list mode in pwsh 7.x If running an exe, see if there is a native PS way (think objects!) ipconfig.exe -> Get-NetIPConfiguration (alias gip) icacls.exe -> Get-ACL & Set-ACL Eat your own dog food aka run your own scripts & fix/improve If it runs in cmd but not PS, work out why rather than admit defeat Special characters Quotes Ctrl z/y, ctrl home/end, ctrl backspace/delete (Get-PSReadLineKeyHandler)
error, get the hell out of Dodge (abort! abort!) But do you need to expose the actual error? Can you script around it? Can you output a link for more information/fix/workaround ? Write-Warning instead ? Don’t try/catch an exception & just output “there was an error” $ErrorActionPreference = ‘SilentlyContinue’ – NO!!! -ErrorAction SilentyContinue –ErrorVariable thisSpecificError Try/catch with comment if ignoring exception (check it’s expected exception)
compile Unless protecting IP & methods are not always 100% secure Don’t be embarrassed Likelihood of something similar is usually high – why reinvent the wheel? Ask the community for feedback Accept suggestions, improvements & criticism graciously
identifiers – no $i or $pw Tab completion so length/brevity doesn’t matter & decreases tpyo [sic] risk Set-StrictMode –Version Latest (when developing/testing, not in script itself) Comments but allow code to be self-documenting as much as possible PowerShell Approved Verbs – Verb-Noun for functions Spaces are not evil – embrace the space No cmdlet/function aliases No parameter abbreviations No positional parameters & use non-abbreviated named ones (tab complete) Use parameters, with defaults, not variables that need editing in script
Don’t use Write-Host unless you really, really have to Output helpful information with Write-Verbose so can be silenced without changing code But use breakpoints in ISE or VS Code for debugging Be careful with Write-Output if your script outputs objects – pipeline pollution Write-Debug can be useful but watch for it prompting to continue Use Write-Progress cautiously as can slow execution massively Write-Information ?? Redirection of individual streams useful to separate them out (N>file)
it copies the existing array to new Hashtables (aka dictionaries) are great for caching Keep loops lean & mean – evaluate as much outside as possible Outputting objects in a loop & assigning to variable can be quicker Beware pipeline pollution Beware Where-Object on large arrays Hashtable instead BinarySearch method of Generic collections if they are sorted Consider using runspaces for parallelisation Jobs can be slow ForEach-Object –Parallel in pwsh 7.x