Perserving Command History Across Sessions

Perserving Command History Across Sessions

  • Comments 27

<Edited 7/2/2006 to add tags and Categories>

Ben Winzenz didn't like the fact that Windows PowerShell did not maintain history lists between sessions (http://winzenz.blogspot.com/2006/06/cool-mshpowershell-tidbit.html) .   We hear you Ben.  Back to my least favorite phrase, "to ship is to choose".  That said, we try to give you in the community the power to do that which we cannot.  Here is some code that you can put in your profile file that defines a function BYE which saves off your sessions history into a History.CSV file in your home directory and then adds that to your history when you startup the next session.  You get to control how much of the history you want (up to 32KB-1) but I just do 1KBs worth.

$MaximumHistoryCount = 1KB

if (!(Test-Path ~\PowerShell -PathType Container))
{   New-Item ~\PowerShell -ItemType Directory
}

function bye
{   Get-History -Count 1KB |Export-CSV ~\PowerShell\history.csv
    exit
}

if (Test-path ~\PowerShell\History.csv)
{   Import-CSV ~\PowerShell\History.csv |Add-History
}

I was going to put comments in the code but thought I would test out my assertion that VERBOSITY produces self-documenting scripts.  I think it does but you can let me know one way or the other.

So add this to your startup and then do a session, type BYE instead of EXIT and then start a new session and do a Get-History.   You'll see a bunch of commands already in your list. 

Now lets have a little fun with History, do what I instructed above and get into your new session.  Now do a Get-History and pipe it to Get-Member:


PS> Get-History |Get-Member -MemberType Property
   TypeName: Microsoft.PowerShell.Commands.HistoryInfo

Name               MemberType Definition
----               ---------- ----------
CommandLine        Property   System.String CommandLine {get;}
EndExecutionTime   Property   System.DateTime EndExecutionTime {get;}
ExecutionStatus    Property   System.Management.Automation.Runspaces.Pip...
Id                 Property   System.Int64 Id {get;}
StartExecutionTime Property   System.DateTime StartExecutionTime {get;}

This means that you can find out when something was executed (e.g. which session it happened in) using the following command:

PS> ghy |ft id,endexecutiontime,commandline -auto

 Id EndExecutionTime      CommandLine
 -- ----------------      -----------
612 6/29/2006 5:39:34 AM  gcm export-csv |fl *
613 6/30/2006 6:51:16 PM  ipconfig
614 6/30/2006 8:51:38 PM  cd C:\kits
...

Enjoy!
Jeffrey P. Snover
Windows PowerShell Architect

PSMDTAG:FAQ: How do I perserve command history across sessions?

PSMDTAG:FAQ:  Can I run an exit script?


PSMDTAG:ENVIRONMENT: History

PSMDTAG:SHELL: shutdown, startup, exitScript

Leave a Comment
  • Please add 6 and 5 and type the answer here:
  • Post
  • PingBack from http://www.winterdom.com/weblog/2008/02/28/TheCommandHistoryInPowerShell.aspx

  • PingBack from http://thought.mobiforumz.com/2006/07/02/mshpowershell-followup/

  • PingBack from http://winzenz.mobiforumz.com/2006/07/02/mshpowershell-followup/

  • Is there a way to import the data so that it's available when pressing F7?

  • See http://blogs.msdn.com/powershell/archive/2008/06/11/powershell-eventing-quickstart.aspx

  • Still no normal resolution for history ?

  • Thanks for the great little tutorial! I'm a UNIX/Linux user who is trying to get to grips with PowerShell.

    One thing I've not managed through your little tutorial is to get the arrow keys to work. So I can:

    1. export a session history

    2. close session

    3. import previous session history

    4. use the up-arrow key to get to a point in imported history

    1-3 works fine. I can do a get-history and see that all is imported, but 4 does not work! It only lets me access the current session history.

    Your help would be appreciated.

  • Same here. I would like the arrow keys to scroll through the imported history. More details on how to use the event hook are here stackoverflow.com/.../powershell-history-how-do-you-prevent-duplicate-commands.

  • For crying out loud.  Microsoft, a multi-billion dollar corporation creates the Power Shell and it doesn't preserve the history across sessions.  You have to write a script.  Jesus, how freaking lame.  Make it save history by default.  Oh, that's right, Linux is lame.  Can't do it like they do it.  God forbid.

    Well enough of my rant, but I felt it needed to be said.

    If you don't like what I just said, oh well.  You know what they say about opinions.

  • You can als use the exit command if you add the following line:

    register-engineevent PowerShell.Exiting -action { bye }

  • so after all these years microsoft can only come up with a prompt still without history. good to go. I understand the monster you've created is unharnessable.

  • So I replaced his script with this to catch the "exiting" event instead of having to type "bye".  Doesn't work if you click the window's "x" though:

    $MaximumHistoryCount = 1KB

    if (!(Test-Path ~\PowerShell -PathType Container))

    {

    New-Item ~\PowerShell -ItemType Directory

    }

    if (Test-path ~\PowerShell\History.csv)

    {

    Import-CSV ~\PowerShell\History.csv |Add-History

    }

    register-engineevent PowerShell.Exiting -action {

    Get-History -Count 1KB |Export-CSV ~\PowerShell\history.csv

    exit

    }

Page 2 of 2 (27 items) 12