Powershell code formatting and coding style and style guides: some links and elaboration
Posted by jpluimers on 2022/07/05
I started doing occasional PowerShell “work” long before Visual Studio Code came along with its [Wayback] PowerShell Extension.
Back then, my tool of choice was PowerGUI: Settling on PowerGUI for PowerShell development. Before that it was PowerShell ISE.
Since then, I fiddled around a bit with Visual Studio Code, but not much. Then I got treated for rectum cancer, and when writing this, I’m back to Visual Studio code with the PowerShell Extension and already figured out a lot has improved.
One of the things is code formatting. Back some 7 years ago, this was all not set in stone. Now it is, so it is important to adhere to.
I already posted Code Layout and Formatting: Indentation · PowerShell Practice and Style last year, so now it is good repeat the link in it and add some more.
For my link archive:
- [WayBack] Code Layout and Formatting · PowerShell Practice and Style which I found out is open source at [Wayback/Archive.is] PoshCode/PowerShellPracticeAndStyle: The Unofficial PowerShell Best Practices and Style Guide;
- the guides’ markdown code itself is at [Wayback/Archive.is] PowerShellPracticeAndStyle/Style-Guide at master · PoshCode/PowerShellPracticeAndStyle.
- there is also a best practices markdown code at [Wayback/Archive.is] PowerShellPracticeAndStyle/Best-Practices at master · PoshCode/PowerShellPracticeAndStyle
The Visual Studio Code code formatter for PowerShell follows this style guide closely.
- [Wayback/Archive.is] PowerShell-Docs style guide – PowerShell | Microsoft Docs also has an interesting section named “Coding style rules”. It’s far less comprehensive than the above PoshCode documentation.
- [Wayback/Archive.is] PowerShell editing with Visual Studio Code is a comprehensive page linking to many resources, including a few below
- [Wayback/Archive.is] PowerShell/PSScriptAnalyzer: Download ScriptAnalyzer from PowerShellGallery is the foundation on which a lot of the Visual Studio Code support for PowerShell rests.
- [Wayback/Archive.is] PSScriptAnalyzer/Engine/Settings at master · PowerShell/PSScriptAnalyzer defines the settings, including formatter related ones.
- [Wayback/Archive.is] Pester – The ubiquitous test and mock framework for PowerShell | Pester is built into Windows 10 and Windows Server 2016.
- [Wayback/Archive.is] PowerShellEditorServices/LanguageServerSettings.cs at master · PowerShell/PowerShellEditorServices hooks the code formatter (Ctrl+Alt+F)
Elaborating on code formatting and strictness
An overview of styles (BSD/Allman, 1TBS/OTBS/K&R, Stroustrup) with PowerShell examples is in [Wayback/Archive.is] There is no One True Brace Style · Issue #81 · PoshCode/PowerShellPracticeAndStyle.
You can manually run the PSScriptAnalyzer
formatter as well, which for instance allows formatting to be part of a CI/CD, or even pre-commit. See [Wayback/Archive.is] PSScriptAnalyzer/Invoke-Formatter.md at master · PowerShell/PSScriptAnalyzer.
[Wayback/Archive.is] Consistent Script formatting · Issue #9 · microsoft/CSS-Exchange already went this route with this little script (which itself is in the for PowerShell less practical and therefore less popular Allman style):
Import-Module PSScriptAnalyzer $content = Get-Content .\Setup\SetupAssist.ps1 $stringContent = [string]::Empty foreach($line in $content) { $stringContent += "{0}`r`n" -f $line } $test = Invoke-Formatter $stringContent -Setting .\settings\codeformatting.psd1 if ($test -ne $content) { throw "failed to meet code formatting requirements" }
[Wayback/Archive.is] Style Checking for PowerShell Scripts. · Issue #829 · Azure/azure-sdk-tools is not yet completed, and also proposes to use Set-StrictMode
(see [Wayback/Archive.is] Set-StrictMode (Microsoft.PowerShell.Core) – PowerShell | Microsoft Docs). I prefer Set-StrictMode -Version Latest
for the simple reason that it will break with useful suggestions as soon as possible as not increase technical debt.
Note that if your script also uses
param
, then theparam
needs to be in front ofSet-StrictMode
, otherwise you will get errors likeThe variable '$MyParameter' cannot be retrieved because it has not been set.
for any parameter you define.See [Wayback/Archive.is] Set-StrictMode does not cover the whole PowerShell script – Stack Overflow and [Wayback/Archive.is] about Scripts: Parameters in Scripts – PowerShell | Microsoft Docs
… The
Param
statement must be the first statement in a script, except for comments and any#Require
statements…
If you want to dive deeper into using PSScriptAnalyzer
, then definitely read these blog posts:
- [Wayback/Archive.is] PSScriptAnalyzer deep dive – Part 1 of 4: Getting started with PSScriptAnalyzer – Scripting Blog
- [Wayback/Archive.is] PSScriptAnalyzer deep dive – Part 2 of 4: Suppressing, including, excluding rules – Scripting Blog
- [Wayback/Archive.is] PSScriptAnalyzer deep dive – Part 3 of 4: Wrapping PSScriptAnalyzer with Pester to get formatted results – Scripting Blog
- [Wayback/Archive.is] PSScriptAnalyzer deep dive – Part 4 of 4: Writing custom rules – Scripting Blog
Since PowerShell 3 (it feels like yesterday, but it was introduced 10 years ago with Windows 8 and Windows Server 2012), the PowerShell command-line is based on [Wayback/Archive.is] PowerShell/PSReadLine: A bash inspired readline implementation for PowerShell:
This module replaces the command line editing experience of PowerShell for versions 3 and up. It provides:
- Syntax coloring
- Simple syntax error notification
- A good multi-line experience (both editing and history)
- Customizable key bindings
- Cmd and emacs modes (neither are fully implemented yet, but both are usable)
- Many configuration options
- Bash style completion (optional in Cmd mode, default in Emacs mode)
- Bash/zsh style interactive history search (CTRL-R)
- Emacs yank/kill ring
- PowerShell token based “word” movement and kill
- Undo/redo
- Automatic saving of history, including sharing history across live sessions
- “Menu” completion (somewhat like Intellisense, select completion with arrows) via Ctrl+Space
The “out of box” experience is meant to be very familiar to PowerShell users – there should be no need to learn any new key strokes.
Keith Hill wrote a great introduction to
PSReadLine
here.Ed Wilson (Scripting Guy) wrote a series on
PSReadLine
, starting here.
These last two links are:
- [Wayback/Archive.is] PSReadLine: A Better Line Editing Experience for the PowerShell Console | Keith Hill’s Blog
- [Wayback/Archive.is] PSReadLine – Scripting Blog (continued on [Wayback/Archive.is] PSReadLine: page 2 – Scripting Blog) referring to these articles (which I reordered in chronological order):
-
- [Wayback/Archive.is] The Search for a Better PowerShell Console Experience – Scripting Blog
- [Wayback/Archive.is] A Better PowerShell Command-Line Edit – Scripting Blog
- [Wayback/Archive.is] Better PowerShell History Management with PSReadLine – Scripting Blog
- [Wayback/Archive.is] Useful Shortcuts from PSReadLine PowerShell Module – Scripting Blog
- [Wayback/Archive.is] A Better PowerShell Console with Custom PSReadLine Functions – Scripting Blog
-
Especially the part about useful shortcuts helped me with my productivity and demo preparation (a bit reformatted):
I decide to map two keys to two functions. The first is
EnableDemoMode
and the second isDisableDemoMode
. The key bindings are shown here:Set-PSReadlineKeyHandler -Key ^E -Function EnableDemoMode Set-PSReadlineKeyHandler -Key ^D -Function DisableDemoMode
Demo mode is cool, and it is not only for demonstrations. It is useful as I experiment with using
PSReadLine
. It is also great for teaching Windows PowerShell classes and giving presentations. Why? Well, when Demo mode is turned on, it displays every key that is typed. This includes the Ctrl and the Alt keys, but not SHIFT.When reading the Demo mode, realize that the most recently typed command is on the left side of the screen. In the following image, I first turned on
WhatIsKey
by typing Alt+?. Next I typed Ctrl+D to see key mapping for that key combination.
You can set these or similar keybindings in your PowerShell profile as well, as for instance [Wayback/Archive.is] PowerShell Gallery | SamplePSReadlineProfile.ps1 1.0.0.8 shows.
–jeroen
Keybindings in PowerShell 5.1 on Windows 10
I pressed Shift+Alt+? in my maximised PowerShell console, and voilà:
PS C:\Users\jeroenp> Basic editing functions ======================= Enter AcceptLine Accept the input or move to the next line if input is missing a closing token. Shift+Enter AddLine Move the cursor to the next line without attempting to execute the input Backspace BackwardDeleteChar Delete the character before the cursor Ctrl+h BackwardDeleteChar Delete the character before the cursor Ctrl+Home BackwardDeleteLine Delete text from the cursor to the start of the line Ctrl+Backspace BackwardKillWord Move the text from the start of the current or previous word to the cursor to the kill ring Ctrl+C Copy Copy selected region to the system clipboard. If no region is selected, copy the whole line Ctrl+c CopyOrCancelLine Either copy selected text to the clipboard, or if no text is selected, cancel editing the line with CancelLine. Ctrl+x Cut Delete selected region placing deleted text in the system clipboard Delete DeleteChar Delete the character under the cursor Ctrl+End ForwardDeleteLine Delete text from the cursor to the end of the line Ctrl+Enter InsertLineAbove Inserts a new empty line above the current line without attempting to execute the input Shift+Ctrl+Enter InsertLineBelow Inserts a new empty line below the current line without attempting to execute the input Ctrl+Delete KillWord Move the text from the cursor to the end of the current or next word to the kill ring Ctrl+v Paste Paste text from the system clipboard Shift+Insert Paste Paste text from the system clipboard Ctrl+y Redo Redo an undo Escape RevertLine Equivalent to undo all edits (clears the line except lines imported from history) Ctrl+z Undo Undo a previous edit Alt+. YankLastArg Copy the text of the last argument to the input Cursor movement functions ========================= LeftArrow BackwardChar Move the cursor back one character Ctrl+LeftArrow BackwardWord Move the cursor to the beginning of the current or previous word Home BeginningOfLine Move the cursor to the beginning of the line End EndOfLine Move the cursor to the end of the line RightArrow ForwardChar Move the cursor forward one character Ctrl+] GotoBrace Go to matching brace Ctrl+RightArrow NextWord Move the cursor forward to the start of the next word History functions ================= Alt+F7 ClearHistory Remove all items from the command line history (not PowerShell history) Ctrl+s ForwardSearchHistory Search history forward interactively F8 HistorySearchBackward Search for the previous item in the history that starts with the current input - like PreviousHistory if the input is empty Shift+F8 HistorySearchForward Search for the next item in the history that starts with the current input - like NextHistory if the input is empty DownArrow NextHistory Replace the input with the next item in the history UpArrow PreviousHistory Replace the input with the previous item in the history Ctrl+r ReverseSearchHistory Search history backwards interactively Completion functions ==================== Ctrl+Space MenuComplete Complete the input if there is a single completion, otherwise complete the input by selecting from a menu of possible completions. Tab TabCompleteNext Complete the input using the next completion Shift+Tab TabCompletePrevious Complete the input using the previous completion Miscellaneous functions ======================= Ctrl+l ClearScreen Clear the screen and redraw the current line at the top of the screen Alt+0 DigitArgument Start or accumulate a numeric argument to other functions Alt+1 DigitArgument Start or accumulate a numeric argument to other functions Alt+2 DigitArgument Start or accumulate a numeric argument to other functions Alt+3 DigitArgument Start or accumulate a numeric argument to other functions Alt+4 DigitArgument Start or accumulate a numeric argument to other functions Alt+5 DigitArgument Start or accumulate a numeric argument to other functions Alt+6 DigitArgument Start or accumulate a numeric argument to other functions Alt+7 DigitArgument Start or accumulate a numeric argument to other functions Alt+8 DigitArgument Start or accumulate a numeric argument to other functions Alt+9 DigitArgument Start or accumulate a numeric argument to other functions Alt+- DigitArgument Start or accumulate a numeric argument to other functions PageDown ScrollDisplayDown Scroll the display down one screen Ctrl+PageDown ScrollDisplayDownLine Scroll the display down one line PageUp ScrollDisplayUp Scroll the display up one screen Ctrl+PageUp ScrollDisplayUpLine Scroll the display up one line Ctrl+Alt+? ShowKeyBindings Show all key bindings Alt+? WhatIsKey Show the key binding for the next chord entered Selection functions =================== Ctrl+a SelectAll Select the entire line. Moves the cursor to the end of the line Shift+LeftArrow SelectBackwardChar Adjust the current selection to include the previous character Shift+Home SelectBackwardsLine Adjust the current selection to include from the cursor to the end of the line Shift+Ctrl+LeftArrow SelectBackwardWord Adjust the current selection to include the previous word Shift+RightArrow SelectForwardChar Adjust the current selection to include the next character Shift+End SelectLine Adjust the current selection to include from the cursor to the start of the line Shift+Ctrl+RightArrow SelectNextWord Adjust the current selection to include the next word Search functions ================ F3 CharacterSearch Read a character and move the cursor to the next occurence of that character Shift+F3 CharacterSearchBackward Read a character and move the cursor to the previous occurence of that character PS C:\Users\jeroenp>
.
Leave a Reply