Quickly Finding Previously Typed Commands With PowerShell
Table of Contents
I often find myself needing to re-use commands on Windows that I know for a fact I’ve used a few weeks or even months back but I don’t remember the exact format of. If you’ve ever used ffmpeg
for anything more serious than just a vanilla conversion of one video file to another format, you know exactly what I am talking about.
Finding commands with one command #
Now, the traditional way of doing this would be using the ↑ key to scroll through the myriad of commands, but that is painful. There has to be a better way. And there is!
In PowerShell, this can be done with the help of Get-History
(or, history
for short). If you use the command as-is, you will get the list of commands that you’ve typed in within the current session:
PS C:\Users\den> history
Id CommandLine
-- -----------
1 Get-History
2 history
3 ls
4 Get-History
5 cls
PS C:\Users\den>
Alright, it’s useful, but not terribly useful for the problem that I mentioned above - what if the command I am looking for was typed months ago? For that, we do this:
Get-Content (Get-PSReadlineOption).HistorySavePath
PowerShell stores the command history in a file! That file is usually located in your application data directory:
C:\Users
\den
\AppData
\Roaming
\Microsoft
\Windows
\PowerShell
\PSReadLine
\ConsoleHost_history.txt
You can open the file with your favorite text editor to peek inside its contents. The full command I showed above uses Get-PSReadlineOption
to retrieve the current settings for the PSReadline
module, which is responsible for managing the command-line editing and history in PowerShell. The resulting PSConsoleReadLineOptions
instance contains the HistorySavePath
property that, in turn, contains the path to the file that stores the entire command history.
But, looking for the file every time, and then looking for a command within it is still too much work. Can we make it easier? Say, I want to find everything that has ffmpeg
in it. To do that, I can use:
Select-String -Path (Get-PSReadlineOption).HistorySavePath -Pattern 'ffmpeg' | ForEach-Object { $_.Line }
This amalgamation of commands will read the file and only output the lines that contain ffmpeg
. But that’s one heck of a command to remember to type every time. Can we make it even easier? Enhance!
Edit the $PROFILE
file (you can get its path by typing $PROFILE
in the terminal) by adding this function to it:
Function Hmm {
param (
[string]$searchString
)
Select-String -Path (Get-PSReadlineOption).HistorySavePath -Pattern $searchString | ForEach-Object { $_.Line }
}
Now, you can reload the profile with . $PROFILE
and then type in:
hmm ffmpeg
This will get you the full list of commands that ever involved ffmpeg
.
Alternatives #
As a helpful Bluesky community member pointed out, there are also alternative ways to get the history if you don’t want to see the full list of commands printed in the terminal. This is documented on Microsoft Learn.