简体   繁体   中英

PowerShell track history as full objects across sessions

I am a novice using PowerShell 5.1 under Win 10. I am tinkering with history. So far, I managed to have a persistent history across sessions with PSReadline . *

But this is a "limited" persistent history, as only commands are saved in a text file, which is read when launching a new session. So a lot of information on the HistoryInfo objects is lost, in particular the StartExecutionTime . Then,

  1. Get-Content (Get-PSReadlineOption).HistorySavePath gives all commands with no "timestamp", and
  2. Get-History gives commands with timestamp but only for the current session.

I am used to history in bash , which gets both points right.

This old doc (2009) shows a possible workaround. I managed to export all history info before leaving a session with Get-History | Export-Clixml $env:PSDIR'\my_history.xml' Get-History | Export-Clixml $env:PSDIR'\my_history.xml' . Executing Import-Clixml $env:PSDIR'\my_history.xml' | Add-History Import-Clixml $env:PSDIR'\my_history.xml' | Add-History at the beginning of a new session recovers the full history, including timestamps.

What is missing, I guess, is:

  1. A way to automatically export history upon closing the session. I don't even know if this is possible.

  2. Removing the first line in the history after importing, as it contains the importing command itself. I didn't work on this, but I guess I can handle it. Not needed. If the importing command is executed in startup scripts it does not go to history.

Is this a viable way to achieve the intended result? If so, how could I incarnate item 1?

Are there any alternatives?


* Although I could not make it work in the PS ISE .

Thanks to the pointer by RetiredGeek , I could move forward. What I did:

  1. Added Register-EngineEvent PowerShell.Exiting -Action {. $env:PSDIR'\history\save_history.ps1' } Register-EngineEvent PowerShell.Exiting -Action {. $env:PSDIR'\history\save_history.ps1' } to my profile.ps1 .

  2. Created file $env:PSDIR'\history\save_history.ps1' containing Get-History | Export-Clixml $env:PSDIR'\my_history.xml' Get-History | Export-Clixml $env:PSDIR'\my_history.xml'

This almost provides a solution. The only two remaining issues are:

  1. Removing the exit command that is left as the last command in history. This seems manageable.

  2. Make this work when closing by hitting "X". * In this case, I have observed a strange result. If I close session #1 with "X", and open a new session #2, the commands that I have entered in session #1 do not show up at the bottom of Get-History . Nevertheless, they are available with Up/Dpwn arrows. This is likely worth another question.


* As per this , starting with PS v3 the "X" button was hooked up with the exit event. But "X" does not seem to work exactly like exit , given point 2 above.

I know this is an old post but thought i'd share.

in the past i took a long time moving off windows 8.1 and was managing my history without psreadline and just powershells add- clear- get- history commands. I wanted to save the history to a file and when loading a new session, have it read in the file.

I'd done the same using the Register-EngineEvent, but got frustrated losing the history if the terminal crashed or I 'x'ed out by mistake.

While I dont use the trick anymore, I did for a while. The trick was to have a snippet in my prompt function to append the last item in get-history to a csv file. Sure its ugly and a write to disk for each command you issue, but it worked for me and in case it tickles your fancy it worked like this:

  • set some environment variable to save the history too in you profile.
  • check if the file exists and add the history from it in your profile
  • create a custom prompt that appends the last item from get-history to the csv file.

so for example in your profile

# in your profile somewhere 
$Env:MyPoshHistory = "$($env:USERPROFILE)\MyPoshHistory.csv"
If ( Test-Path $Env:MyPoshHistory ) { 
  Add-History -InputObject $( Import-Csv $Env:MyPoshHistory )
}

and then in your prompt add

If ($Env:MyPoshHistory) {
  Get-History | Select-Object -Last 1  | Export-Csv $Env:MyPoshHistory -Append
}

If your not sure how to add to your prompt, (which is just a function in powershell), see https://ss64.com/ps/syntax-prompt.html

easiest way is to define a function called prompt in your profile

   function prompt { 
    If ($Env:MyPoshHistory) {
      Get-History | Select-Object -Last 1  | Export-Csv $Env:MyPoshHistory -Append
    }
     'PS ' + $pwd + '> ' 
   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM