- Author and member of the year 2019 – Why DevOps still doesn't rule the IT world - Wed, Jan 1 2020
- Results of the 4sysops member and author competition in 2018 - Tue, Jan 8 2019
- Why Microsoft is using Windows customers as guinea pigs - Reply to Tim Warner - Tue, Dec 18 2018
You’ve probably heard that Windows 10 gets a new PowerShell console. It is about time for Microsoft to improve the console, which hasn’t changed much since the MS DOS times, considering how important command-line administration has again become in Windows. Whereas these console improvements are welcome, they don’t make PSReadLine obsolete. Quite the contrary—in combination with the new Windows 10 features, the PowerShell console is inching closer to the most developed Linux consoles.
Note that I am not speaking of the language features here. In many areas, PowerShell has already surpassed its models from the UNIX world. PSReadLine doesn’t change PowerShell’s language capabilities; it only improves the way you edit commands and scripts.
The first feature that catches the eye when you start typing on a PowerShell console after you import the PSReadLine module is syntax coloring. PowerShell purists often criticize that Windows GUIs are just too colorful. (I have even seen CLI gurus working on black-and-green consoles while punching in their super-geeky PowerShell commands.) Nevertheless, I feel that, for the PowerShell beginner in particular, syntax highlighting offers valuable support and helps avoid syntax errors.
PSReadLine also has a simple error notification feature. When the module detects a syntax error in the current line, the greater-than sign in the PowerShell prompt turns red. For example, if quotes are missing in your command, PSReadLine will draw your attention to the problem. Unfortunately, the tool does not underline the position in the command where it found the error, as in PowerShell ISE.
Syntax error notification
If you miss the syntax error notification and press ENTER, PSReadLine sometimes ensures that the command isn’t executed and displays a warning instead.
Syntax error warning
The module also detects when you are trying to run a command that doesn’t exist. By pressing ENTER a second time, you can insist that your command is run; however, this will only get you PowerShell’s intimidating red error message. Therefore, you had better trust PSReadLine and just correct your typo, which you can do quickly because the incorrect command is still at the prompt.
Command cannot be found warning
One of my favorite features of PSReadLine is that it allows you to mark, copy, and paste text in the common Windows way. That is, you can press SHIFT and then move the cursor to select text. The CTRL+SHIFT+ArrowKeys key combination allows you to select words, SHIFT+END selects the rest of the line, etc. You know what I mean. CTRL+C copies text, CTRL+X cuts text, and CTRL+V pastes the text from the clipboard. Just in case you are wondering whether you can still use CTRL+C to abort a script or clear a command line, yes, you can. PSReadLine only changes the key binding of CTRL+C when text is selected.
These editing features come in handy if you need multiple lines for accomplishing your automation task. SHIFT+ENTER opens a new line with a continuation prompt at the beginning. In PowerShell, you can do this with the backtick (`); however, if you then try to change previous lines by pressing the up-arrow key, PowerShell will stay in the current line and cycle through the command history.
With PSReadLine, you can move the cursor as you would in an editor, and you can even select text across multiple lines. However, you can’t use the up-arrow and down-arrow keys for the latter. To select multiple lines of text, you have to press SHIFT+END and then press the right-arrow key. If you want to select the entire script, you can press CTRL+A.
Selecting text across multiple lines
Multiline editing even works when you access previous commands through the history function. If you entered a command with multiple lines, you can access and edit the script through the history function by pressing the left-arrow key when you reach the multiline command.
Speaking of the history function, PSReadLine has a nice search feature that allows you to find previous commands promptly. You can also use PowerShell’s Get-History (alias h) cmdlet to search in your command history. However, this usually involves so much typing that it is often faster to just re-enter the entire command.
With PSReadLine, if you press CTRL+R (reverse history), you will see a prompt with a nice search-as-you-type feature. The function finds the text you enter at any position within the command (not just at the beginning of the command as F8 does in the PowerShell console), and you can then modify the found command right away. CTRL+S invokes forward search.
Searching command history
What I really find cool is that PSReadLine preserves the history across sessions. If you close the console, the commands of previous sessions are still stored in the history. You can also access the history across simultaneously running consoles by using PSReadLine’s history search function. However, PSReadLine does not change PowerShell’s own history list. For instance, the Get-History cmdlet or F7 will continue to show only the entered commands of your current session.
Another highlight of PSReadLine is the menu complete feature. If you press CTRL+SPACE, you will get a list of available options. For example, if you enter the name of a cmdlet plus “-” and press CTRL+SPACE, you will see a menu with all available parameters. You can then select a parameter with the cursor. If you press ENTER, you execute the cmdlet with the parameter. If you want to continue editing your command, just press the spacebar.
Menu completion works in every thinkable situation where you are unsure how to continue. If you can’t recall the exact name of a cmdlet, start typing as far as you remember and then press CTRL+SPACE. Invoking menu completion after entering a cmdlet name (plus blank) will show you the available options when you run the cmdlet. For instance, Get-Process + CTRL+SPACE will display a list of processes, and Get-Process | Select + CTRL+SPACE will list the properties of the process object. Thus, with PSReadLine, you will get the same auto-completion comfort as in PowerShell ISE.
PSReadLine was probably originally directed at UNIX admins who converted in droves to Windows when PowerShell was introduced. Many of the module’s features allow you to change the behavior of the PowerShell console so that Linux admins get a homey feeling.
If you are one of those renegades, you might like PSReadLine’s emacs mode. Emacs is a text editor that was introduced about 40 years ago and can be seen as the grandfather of all modern editors. PSReadLine only offers a few of the emacs features, but, if you feel like it, you can now kill and yank (for the Windows admin: this is just emacs geek speak for cut and paste) in emacs style on a PowerShell console.
I somehow doubt that the average Windows admins will make friends with emacs mode, which is probably why PSReadLine runs by default in Windows mode. If you are interested in a history lesson, you can enable emacs mode with this command:
Set-PSReadlineOption -EditMode Emacs
To get a list of all key bindings, you can then enter this command:
Key bindings in emacs mode
This cmdlet also displays commands without key binding. If you only want to display a list of all available shortcuts, you can press SHIFT+CTRL+ALT+/ on a US keyboard. If you have another keyboard layout, the key combination is SHIFT+CTRL+ALT+OEM2. I think that, on most keyboards, the OEM2 key is the last one before ENTER in the row that starts with A.
If terms like yank-pop (cycle through options) or kill ring (kind of a clipboard with multiple entries) don’t mean anything to you, you can switch back to Windows mode with this command:
Set-PSReadlineOption -EditMode Windows
However, if you like some of the emacs mode features, it is possible to change just some of the key bindings in Windows mode. I personally like the bash auto-complete style. Pressing TAB on a PowerShell console allows you to cycle through all matches. But if you press TAB on a bash shell, a complete list of available options will be displayed.
For instance, if you want to run a program in your current directory, you can type the first letters and then press TAB. PSReadLine will present a list of options if multiple files in the directory match your entry. However, a common PowerShell console (or a command prompt, for that matter) will jump to the first file that matches your entry. I often make the mistake of pressing ENTER too early because I wrongly assumed that only one command fits. With PSReadLine’s bash-style auto-completion, this can’t happen because it will complete the command only if just one match exists; otherwise, it will show you a list of all matching files.
Bash-style TAB completion
If you like to work with bash-style auto-completion in PSReadLine’s Windows mode, you can change the key binding with this command:
Set-PSReadlineKeyHandler -Key Tab -Function Complete
I can’t cover all of PSReadLine’s features here. If you want to learn more about the tool, you can read its help text. After you import the module, you get a general introduction with Get-Help about_PSReadline, and Get-Help PSReadLine lists the available cmdlets. Also check out the module’s options with Set-PSReadlineOption + CTRL+SPACE.
Just a final tip: try the Windows-style “kill ring” tool ClipX. It allows you to access previous clipboard entries. The free utility doesn’t work on a conventional PowerShell console, but it harmonizes well with PSReadLine.