PowerShells Clear-History doesnt clear history

PowerShells Clear-History doesnt clear history

On Windows 10, the history and sensitive data show up again in future sessions, even after Alt+F7 and clear-history. It turns out the history is stored in a text file found at:

(Get-PSReadlineOption).HistorySavePath

Delete the offending line from that file and end the current session (or clear it via CBs answer).

You can upvote this request for an easier way to temporarily disable the history.

tl;dr

  • There are two histories to clear:

    • PowerShells own (Clear-History)
    • Additionally, in consoles (terminals), that of the PSReadLine module that is used for command-line editing by default in PowerShell v5+ ([Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory())
  • In versions 1.2+ of PSReadLine (verify with Get-Module PSReadLine) pressing Alt+F7 performs both calls for you, and therefore fully clears the in-session history.

    • However, it does not clear the saved history that has accumulated up to this point, so even the cleared sessions history will resurface in future sessions.

    • To also clear the saved history, you have to manually delete the file in which the saved session is stored ((Get-PSReadlineOption).HistorySavePath), as discussed below, and as wrapped by the Clear-SavedHistory function in the bottom section.


To complement CB.s helpful answer and JVimess helpful answer:

  • PowerShells own history mechanism (Get-History, Clear-History) is host-independent, which is why – somewhat unexpectedly – you also need to clear the hostss command history separately.

  • As for the console hosts own history feature:

    • doskey-style history feature, before module PSReadline shipped with PowerShell (see below):

      • There is no saved history – a history is kept only for the duration of the current session.
      • Alt+F7 must be used to clear the consoles history, with no (obvious) programmatic way to do it (in a cmd.exe console window you could use doskey /reinstall, but that doesnt work in PS).
      • CB.s answer shows you how to simulate this keyboard combination; remember: this must be used in addition to Clear-History.
    • The PSReadline module comes with PowerShell v5 and v5.1 on Windows 10 and will also ship with Windows Server 2016, and also ships with the cross-platform Powershell (Core) v7+ edition; it replaces the doskey-style line-editing and command-history features with more sophisticated functionality; it is also possible to retrofit older Windows editions / PS versions (>= v3) versions with it, using the PowerShell Gallery (PSv3 and PSv4 must first install PowerShellGet).

      • Command history is now saved across sessions, in file
        (Get-PSReadlineOption).HistorySavePath.
      • [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() can be used to clear the current sessions history (note that v1.2+ also supports Alt+F7 for interactive clearing of the current history).
        • CAVEAT: With PSReadlines default history-saving style, SaveIncrementally, any sensitive commands have already been saved by the time to you call [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory(), and will reappear in the next session.
        • The only way to handle this is to remove the saved-history file, as demonstrated in JVimess answer which, however, invariably wipes out the entire history.
        • IF you set up your profile to call Set-PSReadlineOption -HistorySaveStyle SaveAtExit every time a session starts – the setting apparenly does NOT stick by itself – you should be able to get away with only calling [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() (in addition to Clear-History) without also having to delete the saved-history file, in which case you wont lose your saved history from previous sessions. HOWEVER, AS OF v2.1.0 (the latest as of this writing), SaveAtExit is BROKEN ALTOGETHER – no history is saved at all; see https://github.com/lzybkr/PSReadLine/issues/262

The following advanced function bundles all commands necessary to clear the command history (both for PowerShell itself and the console), both for doskey-style and PSReadline-module PowerShell console windows:

Note:

  • Because its (currently) the only safe option, PSReadlines saved-history file is deleted as well, which means the entire history, including from previous sessions, is cleared.

  • Therefore, a confirmation prompt is shown by default.

<#
# .SYNOPSIS
#  Clears the command history, including the saved-to-file history, if applicable.
#>
function Clear-SavedHistory {
  [CmdletBinding(ConfirmImpact=High, SupportsShouldProcess)]
  param(    
  )

  # Debugging: For testing you can simulate not having PSReadline loaded with
  #            Remove-Module PSReadline -Force
  $havePSReadline = ($null -ne (Get-Module -EA SilentlyContinue PSReadline))

  Write-Verbose PSReadline present: $havePSReadline

  $target = if ($havePSReadline) { entire command history, including from previous sessions } else { command history } 

  if (-not $pscmdlet.ShouldProcess($target))
  {
        return
  }

  if ($havePSReadline) {
    
    Clear-Host

    # Remove PSReadlines saved-history file.
    if (Test-Path (Get-PSReadlineOption).HistorySavePath) { 
      # Abort, if the file for some reason cannot be removed.
      Remove-Item -EA Stop (Get-PSReadlineOption).HistorySavePath 
      # To be safe, we recreate the file (empty). 
      $null = New-Item -Type File -Path (Get-PSReadlineOption).HistorySavePath
    }

    # Clear PowerShells own history 
    Clear-History

    # Clear PSReadlines *session* history.
    # General caveat (doesnt apply here, because were removing the saved-history file):
    #   * By default (-HistorySaveStyle SaveIncrementally), if you use
    #    [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory(), any sensitive
    #    commands *have already been saved to the history*, so theyll *reappear in the next session*. 
    #   * Placing `Set-PSReadlineOption -HistorySaveStyle SaveAtExit` in your profile 
    #     SHOULD help that, but as of PSReadline v1.2, this option is BROKEN (saves nothing). 
    [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()

  } else { # Without PSReadline, we only have a *session* history.

    Clear-Host
    
    # Clear the doskey librarys buffer, used pre-PSReadline. 
    # !! Unfortunately, this requires sending key combination Alt+F7.
    # Thanks, https://stackoverflow.com/a/13257933/45375
    $null = [system.reflection.assembly]::loadwithpartialname(System.Windows.Forms)
    [System.Windows.Forms.SendKeys]::Sendwait(%{F7 2})

    # Clear PowerShells own history 
    Clear-History

  }

}

PowerShells Clear-History doesnt clear history

To clear the on screen display history (F7) you have to press Alt + F7.

This history is managed by the console buffer, not by PowerShell that has its history clearable by the Clear-History cmdlet.

To script it, try:

[System.Reflection.Assembly]::LoadWithPartialName(System.Windows.Forms)
[System.Windows.Forms.SendKeys]::Sendwait(%{F7 2})

Leave a Reply

Your email address will not be published.