Giving PowerShell a Persistent History of Commands


If you are disappointed that neither Command Prompt nor PowerShell on Windows have the ability to maintain a persistent command history the same way the Linux Terminal does by default, then this blog post is for you.

If you would like to add this capability to the Command Prompt, then the easiest way is to install either of the following applications:

If you would like to add this capability to PowerShell, then follow the following steps:

Open PowerShell in administrator mode and find out which version of PowerShell you have by running for following command:

  • $PSVersionTable.PSVersion

If you have a version that is less than 3, then you need to update your PowerShell. To update to version 3, you must download the Windows Management Framework 3:, then choose either the x86 or the x64 files depending on your system. For x64, I downloaded Windows6.1-KB2506143-x64.msu, Windows6.0-KB2506146-x64.msu

Allow PowerShell to import or use scripts including modules by running the following command:

  • set-executionpolicy remotesigned

Install PsGet by executing the following commands:

Install PSReadline by executing the following command:

  • install-module PSReadline

Open notepad (or better notepad++) in administrator mode and type the following script:

  • $HistoryFilePath = Join-Path ([Environment]::GetFolderPath('UserProfile')) .ps_history
  • Register-EngineEvent PowerShell.Exiting -Action { Get-History | Export-Clixml $HistoryFilePath } | out-null
  • if (Test-path $HistoryFilePath) { Import-Clixml $HistoryFilePath | Add-History }
  • # if you don't already have this configured...
  • Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
  • Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward

Save the file as C:\Users\<username>\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1, where you should replace <username> with the correct folder name on your PC. Do not forget to change the “save as type” option to all files.

Close PowerShell and open it again so that it starts using the script we saved.

From now on, PowerShell will keep the last few hundred commands you typed in its history. Try entering a few commands, and then run the following command to see PowerShell’s history of commands:

  • get-history

Close PowerShell, and then open it again. Enter a few more commands, and then the get-history command. You will see last session’s commands as well as the current session’s commands are there.

You can also scroll through the all your history of commands by using up and down arrow buttons!

For more complete information about compiler optimizations, see our Optimization Notice.



Hi, I had two issues installing PsGet.
One was the unresponsive URL (correct it with ""):

(new-object Net.WebClient).DownloadString("") | iex

The second one was about an SSL related error (it couldn't establish a connection); to resolve this one you have to give another command in the PowerShell BEFORE to dowload PsGet, to change the TLS login parameters:

[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"


I was inspired by this question on StackOverflow.

Another option is to use the PowerShell console prompt function to save the command history as you go. I have this definition in my PowerShell profile:

function global:Prompt { 
    ## Get the last item from the history
    $historyItem = Get-History -Count 1
    ## If there were any history items
      # Save previous command details
      $historyItem | convert-to-tsv | select -skip 1 >> "$global:PowerShellProfileTranscriptFile.command-history.txt"

function global:convert-to-tsv {
  $input |
  ConvertTo-Csv -delimiter "`t" -NoTypeInformation |
  # First  replace: Remove double-quotes 1) at beginning of line 2) at end of line 3) before a tab using regex look-ahead 4) after a tab using regex look-behind
  # Second replace: Replace 2 double-quotes with one (added by convert-to-csv)
  % {$_ -replace '^"|"$|"(?=\t)|(?<=\t)"', '' -replace '""','"' }




It will only work, if I exit the powershell using "exit" command...

It seems that the newer versions of Powershell on Windows 10 have this feature. I quickly confirmed this on my Windows OS which has Powershell Version 5.1 Build 1439. Also, Clink is still a very good option if you want this feature in the simpler command prompt too.

It didn't work for me... I have installed power shell 5 and it doesn't came nativelly the persistant history...

Update for 2017 - Powershell 5 appears to have this functionality built-in.

Thank you for sharing this information.  I was in disbelief this morning when trying to retrieve the command history for a heavy session from yesterday and it was all gone.  Whaaat!!!  So did a search for command history and powershell and your post came up in the results.

Anyway, I typed everything as described for the script but keep getting the following barrage of errors:

Someone online suggested using ISE to run one line at a time but I still can't figure out what's causing the errors.  Thank you.

Join-Path : Cannot bind argument to parameter 'Path' because it is null.
At C:\Users\perezh.PBCOMPANY\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:1 char:29
+ $HistoryFilePath = Join-Path([Environment]::GetFolderPath('UserProfile')).ps_his ...
+                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Join-Path], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.JoinPathCommand
Test-Path : Cannot bind argument to parameter 'Path' because it is null.
At C:\Users\perezh.PBCOMPANY\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:3 char:15
+ if (Test-path $HistoryFilePath) { Import-clixml $HistoryFilePath | add-history }
+               ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Test-Path], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand
Set-PSReadlineKeyHandler : Cannot validate argument on parameter 'Function'. The argument "HistorySearchBackware" does not belong to the set "Abort,AcceptAndGetNext,AcceptLine,AddLine,BackwardChar,BackwardDeleteChar,BackwardDeleteLine,BackwardKillLine,Backw
ous,Undo,UnixWordRubout,ValidateAndAcceptLine,WhatIsKey,Yank,YankLastArg,YankNthArg,YankPop" specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again.
At C:\Users\perezh.PBCOMPANY\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:4 char:49
+ Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackware
+                                                 ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Set-PSReadlineKeyHandler], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,PSConsoleUtilities.SetPSReadlineKeyHandlerCommand

Add a Comment

Have a technical question? Visit our forums. Have site or software product issues? Contact support.