Skip to main content
  1. Writing/

Quickly Finding Previously Typed Commands With PowerShell

·480 words

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.