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.


wj t.'s picture

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

Rami R. (Intel)'s picture

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.

Alexandre V.'s picture

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

Jon G.'s picture

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

Hector R.'s picture

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.