Better PowerShell History Management with PSReadLine
Summary: Microsoft Scripting Guy, Ed Wilson, talks about using PSReadLine to gain better history support in Windows PowerShell.
Microsoft Scripting Guy, Ed Wilson, is here. Someone might have said that those PowerShellers who do not learn how to use command history are doomed to retype the same commands, but I do not recall ever hearing it. In Windows PowerShell there are five *history cmdlets. Of these, I routinely use Get-History (the alias is h) and Invoke-History (alias is r). To be honest, I do not even use these all that often.
One reason, is that the history eventually gets jumbled. Although it is possible to clear the history, or even to delete individual commands from the history that do not work all that well, it often seems a bit like too much work to do all of that. In fact, by using a combination of aliases and tab expansion, it does not take me very long to create a Windows PowerShell command in the first place. So if I have to spend a couple of minutes to find a command via the history, the advantage has been lost, and it is easier to create the command anew.
This is one of the cool things about PSReadLine. It offers better, more sophisticated history support.
Note This is the third post in a series about PSReadLine.
- In The Search for a Better PowerShell Console Experience, I talked about where to get this free module, and how to install it, as well as providing an overview of what it has to offer.
- In A Better PowerShell Command-Line Edit, I talked about the improvements in moving around in the Windows PowerShell console and in the line editing experience after installing PSReadLine.
Today I will talk about the improved history feature.
A short history lesson
One of the cool things about the PSReadLine module is enhanced support for working with Windows PowerShell command history. The following table shows the functions that are included in the module and the keys to which they are bound. Some of the functions are not bound to any keys, and I will talk about that in the second half of today’s post.
Replace the current input with the "previous" item from PSReadLine history.
Replace the current input with the "next" item from PSReadLine history.
Search forward from the current history line interactively.
Search backward from the current history line interactively.
Replace the current input with the "previous" item from PSReadLine history that matches the characters between the start, the input, and the cursor.
Replace the current input with the "next" item from PSReadLine history that matches the characters between the start, the input, and the cursor.
Replace the current input with the last item from PSReadLine history.
Replace the current input with the last item in PSReadLine history, which is the possibly empty input that was entered before any history commands.
In Windows PowerShell, if I do not have the PSReadLine module, and I want to run a command from the command history, I need to first call Get-History so I can see the history items, and then I can get the history number to run the command. This is shown here:
But by using the PSReadLine module, there is a search previous history function that is mapped to the Ctrl-R keystroke combination. When I use this, a reverse search prompt appears at the Windows PowerShell console command line. I type a piece of the command that I am searching for, and it picks through the history and displays matching commands on the line. This is shown here:
If the command is what I am looking for, I simply press ENTER, and the command populates the command console line, clears the search, and runs the command.
Customizing the key mapping
In the previous table, there are several functions that are not mapped to a specific keystroke combination. If a command is unmapped, it is available to be mapped to anything I want. I think it would be useful to map the BeginningOfHistory command to Ctrl+b.
Note Remember key mapping is case sensitive. This makes it possible to map more single stroke commands than would be available otherwise.
To do this, I use the Set-PSReadLineKeyHandler cmdlet and specify the –Key characters as Control b <^b>, and I specify the function as BeginningOfHistory.
Note This is really easy to do. I type the key combination, and PSReadLine automatically translates Ctrl b into ^b for me. I can also use tab expansion for the function name.
The command is shown here:
Set-PSReadLineKeyHandler -Key ^B -Function BeginningOfHistory
Checking key mappings
If I want to see which key mappings and which functions are available, I use the Get-PSReadLineKeyHandler cmdlet. The command and associated output are shown here:
That is all there is to using PSReadLine to work with history. PSReadLine Week will continue tomorrow when I will talk about more cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy