PowerShell的Clear-History不会清除历史记录

Fop*_*ush 40 powershell history

最近我不得不运行一个命令,不幸的是我要求我在命令行输入密码.

之后,我用"清除"清除了我的屏幕,但也希望清除命令历史记录,以便在会话历史记录中不会显示违规命令.遗憾的是,Clear-History cmdlet似乎并没有实际执行其文档所声称的内容 - 运行Clear-History似乎对会话历史记录没有任何影响.

我仍然可以在弹出的历史记录菜单中看到以前的命令,并通过按向上键滚动查看旧命令.这是一个显示问题的screengrab:

PowerShell清除历史记录失败

我已经使用Get-Command验证了Clear-History确实正在执行预期的内置PowerShell cmdlet.

我尝试了一些变体,例如"Clear-History -count 10 -newest",都没有显示出任何效果.当我指定确切的历史ID时,例如"Clear-History -id 3",我收到如下错误:

Clear-History : Cannot locate history for Id 3.
Run Code Online (Sandbox Code Playgroud)

即使我可以在屏幕上看到命令#3.

Vim*_*mes 63

在Windows 10上,即使在Alt + F7和之后,历史记录和敏感数据也会在将来的会话中再次出现clear-history.我找到解决方案是:

Remove-Item (Get-PSReadlineOption).HistorySavePath
Run Code Online (Sandbox Code Playgroud)

然后,结束当前会话或通过CB的答案清除它

  • 仅针对懒惰的管理员,保存命令的文本文件的默认路径为:C:\Users\[username]\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline 下次控制台重新创建该文件开始了。我什至运行了 Remove-Module PSReadline -Force,但是当我再次重新启动控制台时,模块被重新添加(并重新创建了历史文件)。是否有一些超级模块删除功能? (2认同)
  • 也许当他们交付带有PowerShell的模块时,导入它们的工作做得太好了。如果您要禁用的永久历史记录(不是所有其他psreadline [goodies](https://github.com/lzybkr/PSReadLine)),则它[看起来像](https://github.com/lzybkr/ PSReadLine / issues / 163)的方法是将`Set-PSReadlineOption -HistorySaveStyle SaveNothing`添加到您的个人资料中。对于删除模块,也许暂时将该命令放在您的配置文件中就可以了。 (2认同)
  • 很棒的提示,但是为了清除 _current_ 会话的历史记录,使用 `[Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()` 更安全(顺便说一句:在 `PSReadline` v1 中发送 Alt+F7 实际上根本不起作用。 1,这是 Windows 10 附带的版本(Alt+F7 在 v1.2 中引入)。 (2认同)
  • 是的:`Clear-History`是一个PowerShell内部功能,它与host_不相关(但应该_also_被调用); 相比之下,`[Microsoft.PowerShell.PSConsoleReadLine] :: ClearHistory()`清除_host's_历史缓冲区 - 它是PSReadline相当于在PSReadline之前的日期(doskey-style)按Alt + F7.我的回答提供背景. (2认同)

CB.*_*CB. 33

要清除屏幕显示历史记录(F7),您必须按Alt+ F7.

此历史记录由控制台缓冲区管理,而不是由具有Clear-Historycmdlet可清除历史记录的PowerShell管理.

要编写脚本,请尝试:

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.SendKeys]::Sendwait('%{F7 2}')
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 23

补充CB.的有用答案JVimes的有用答案:

  • PowerShell自己的历史记录机制(Get-History,Clear-History)与主机无关,这就是为什么 - 有些出乎意料 - 您还需要单独清除主机的命令历史记录.

  • 至于控制台主机自己的历史记录功能:

    • doskey样式历史记录功能,在PSReadlinePowerShell随附的模块之前(见下文):

      • 没有保存的历史 -历史保持仅在当前会话的持续时间.
      • Alt+F7必须用来清除控制台的历史记录,没有(明显的)编程方式(在cmd.exe你可以使用的控制台窗口中doskey /reinstall,但这在PS中不起作用).
      • CB.的答案向您展示如何模拟这种键盘组合; 记住:除此之外 必须使用Clear-History.
    • PSReadline模块在Windows 10上附带PowerShell v5,并将随Windows Server 2016一起提供 ; 它用更复杂的功能取代了doskey样式的行编辑和命令历史功能 ; 使用PowerShell库(PSv3和PSv4必须首先安装PowerShellGet),还可以使用它来改进旧的Windows版本/ PS版本(> = v3)版本.

      • 现在,命令历史记录在文件中的会话保存
        (Get-PSReadlineOption).HistorySavePath.
      • [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()可用于清除当前会话的历史记录(请注意,v1.2 +还支持Alt+F7交互式清除当前历史记录.
        • CAVEAT:随着PSReadline的默认历史节约型的风格,SaveIncrementally,任何敏感的命令已保存的给你打电话的时候 [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory(),并且将在重新出现在下一个会议.
        • 处理此问题的唯一方法是删除已保存的历史记录文件,如JVimes的答案中所示,然而,这总是会消除整个历史记录.
        • 如果你设置你的个人资料在Set-PSReadlineOption -HistorySaveStyle SaveAtExit每次会话开始时都要打电话- 这个设置本身并没有"坚持" - 你应该只能通过调用[Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()(除此之外Clear-History)而不必删除已保存的历史文件,在这种情况下,您不会丢失以前会话中保存的历史记录.然而,在v1.2中,它SaveAtExit已经是彻底的 - 根本没有历史记录; 请参阅https://github.com/lzybkr/PSReadLine/issues/262

以下高级功能捆绑了清除命令历史记录(PowerShell本身和控制台)所需的所有命令,包括for- doskeystyle和PSReadline-module PowerShell控制台窗口:

注意:

  • 因为它(当前)是唯一的安全选项,所以PSReadline也会删除已保存的历史文件,这意味着将清除整个历史记录,包括以前的会话.

  • 因此,默认情况下会显示确认提示.

<#
# .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 PSReadline's 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 PowerShell's own history 
    Clear-History

    # Clear PSReadline's *session* history.
    # General caveat (doesn't apply here, because we're 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 they'll *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 library's 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 PowerShell's own history 
    Clear-History

  }

}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您提供如此详尽的解释和解决方案。这是应该用来确保 Powershell 的历史记录被正确和完全清除的方法。 (2认同)

小智 8

目前,我唯一的解决方案是通过运行自动化作业定期从文件夹中删除 psreadline.txt 文本。命令的文件路径是@

PS C:\Users\{{user}}\appdata\roaming\microsoft\windows\powershell\psreadline>
Run Code Online (Sandbox Code Playgroud)

文件名是history.txt