【问题标题】:PowerShell's Clear-History doesn't clear historyPowerShell 的 Clear-History 不会清除历史记录
【发布时间】:2012-10-26 19:17:40
【问题描述】:

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

之后,我用“清除”清除了我的屏幕,但也想清除命令历史记录,这样有问题的命令就不会出现在会话历史记录中。不幸的是,Clear-History cmdlet 似乎并没有真正做到其文档声称的那样 - 运行 Clear-History 似乎对会话历史没有任何影响。

我仍然可以在弹出的历史菜单中看到以前的命令,并通过按向上键滚动浏览旧命令。这是一个演示问题的屏幕截图:

我已通过 Get-Command 验证 Clear-History 确实在执行预期的内置 PowerShell cmdlet。

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

Clear-History : Cannot locate history for Id 3.

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

【问题讨论】:

  • 只是一个旁注,但您使用Clear-History 实际清除的历史记录是您使用Get-History 看到的历史记录。

标签: powershell history


【解决方案1】:

在 Windows 10 上,历史记录和敏感数据会在以后的会话中再次出现,即使在 Alt+F7 和 clear-history 之后也是如此。 It turns out 历史记录存储在一个文本文件中:

(Get-PSReadlineOption).HistorySavePath

从该文件中删除有问题的行并结束当前会话(或通过CB's answer 清除它)。

您可以投票this request 以获得更简单的方法来暂时禁用历史记录。

【讨论】:

  • 只是懒惰的管理员,保存命令的文本文件的默认路径是:C:\Users[用户名]\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline 文件是下次启动控制台时重新创建。我什至运行了 Remove-Module PSReadline -Force,但是当我再次重新启动控制台时,模块被重新添加(并重新创建了历史文件)。是否有一些超级模块删除功能?
  • 也许当他们使用 PowerShell 发布模块时,他们在导入它时做得太好了。如果您想要禁用持久性历史记录(不是所有其他 psreadline goodies),那么 looks like 的方法是将 Set-PSReadlineOption -HistorySaveStyle SaveNothing 添加到您的个人资料中。对于删除模块,也许现在将该命令放在您的配置文件中“足够好”。
  • 很好的提示,但是要清除 当前 会话的历史记录,使用 [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() 会更安全(顺便说一句:在 @ 中发送 Alt+F7 实际上根本不起作用987654331@v1.1,这是Windows 10附带的版本(Alt+F7是在v1.2中引入的)。
  • 是:Clear-History 是 PowerShell 内部功能,与主机无关(但应该被调用);相比之下,[Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() 清除 主机的 历史缓冲区 - 它是 PSReadline,相当于在 PSReadline 之前的日子里按 Alt+F7(doskey 样式)。我的回答提供了背景。
  • 仅供参考:您可以投票this request 以获得更简单的方法来暂时禁用历史记录。
【解决方案2】:

tl;dr

  • 两个历史要清除

    • PowerShell 自己的 (Clear-History)
    • 此外,在控制台(终端)中,PSReadLine 模块在 PowerShell v5+ 中默认用于命令行编辑 ([Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory())
  • PSReadLine 的 1.2+ 版本中(使用 Get-Module PSReadLine 验证)Alt+F7 会执行 两个 调用您,因此完全清除会话中历史记录

    • 但是,它确实清除了已保存到目前为止累积的历史记录,所以即使清除的会话的历史记录也会在未来的会议中重新浮出水面

    • 要清除保存的历史记录,您必须手动删除保存会话的文件 ((Get-PSReadlineOption).HistorySavePath) ,如下所述,并由底部的 Clear-SavedHistory 函数包装。


补充CB.'s helpful answerJVimes's helpful answer

  • PowerShell 自己的历史机制(Get-HistoryClear-History)是独立于主机的,这就是为什么 - 有点出乎意料 - 您还需要清除主机的命令历史单独

  • 至于控制台主机自带历史功能

    • doskey-style 历史功能,在模块 PSReadline 随附 PowerShell 之前(见下文):

      • 没有保存历史记录 - 历史记录仅在当前会话期间保留。
      • Alt+F7 必须用于清除控制台的历史记录,没有(明显的)编程方式可以做到这一点(在cmd.exe 控制台窗口中,您可以使用doskey /reinstall ,但这在 PS 中不起作用)。
      • CB.'s answer 告诉你如何模拟这个键盘组合;请记住:除了Clear-History必须在中使用。
    • PSReadline 模块随 Windows 10 上的 PowerShell v5 和 v5.1 一起提供,还将随 Windows Server 2016 提供,并且还随跨平台 Powershell (Core) v7+ 版本;它用更复杂的功能替换了doskey 风格的行编辑和命令历史功能;也可以使用PowerShell Gallery(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's answer 中所示,但是,总是会清除整个历史记录
        • 如果您将个人资料设置为在每次会话开始时调用 Set-PSReadlineOption -HistorySaveStyle SaveAtExit - 该设置显然不会自行“坚持” - 您应该能够逃脱只调用[Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()(除了Clear-History)而不必删除保存的历史文件,在这种情况下,您不会丢失以前会话中保存的历史记录。 但是,从 v2.1.0 开始(撰写本文时的最新版本),SaveAtExit 已完全损坏 - 根本没有保存任何历史记录;见https://github.com/lzybkr/PSReadLine/issues/262

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

注意:

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

  • 因此,默认显示确认提示。

<#
# .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

  }

}

【讨论】:

  • 感谢您提供如此详尽的解释和解决方案。这是应该用来确保正确且完全清除 Powershell 历史记录的方法。
【解决方案3】:

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

此历史记录由控制台缓冲区管理,而不是由 Clear-History cmdlet 可清除其历史记录的 PowerShell 管理。

要编写脚本,请尝试:

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

【讨论】:

  • 狂野。知道是否可以以编程方式复制该功能,以便我可以别名 clear-history 来做这两个?
  • 我已将接受的答案更改为 mklement0,以反映现在需要采取额外措施来完全清除 Windows 7 之后版本中的历史记录。感谢 CB 提供的原始答案为这么多人提供了很好的服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 2011-11-14
相关资源
最近更新 更多