1. ホーム
  2. powershell

[解決済み] PowerShellのClear-Historyで履歴がクリアされない

2023-01-23 21:14:22

質問

最近、あるコマンドを実行する必要があり、その際、残念ながらコマンドライン上でパスワードを入力する必要がありました。

その後、私は "Clear" で画面を消去しましたが、問題のコマンドがセッション履歴に表示されないように、コマンド履歴も消去したいと思いました。残念ながら 履歴を消去 コマンドレットは、そのドキュメントで主張されていることを実際に行っていないようです - Clear-History を実行しても、セッション履歴にまったく影響を与えないようです。

履歴のポップアップ メニューで以前のコマンドを見たり、上キーを押して古いコマンドをスクロールしたりすることは可能です。以下は、この問題を示すスクリーン グラブです。

で検証してみたところ コマンド で確認したところ、Clear-History は確かに期待された組み込みの PowerShell コマンドレットを実行していました。

私は、"Clear-History -count 10 -newest" などのいくつかのバリエーションを試しましたが、すべて何の効果も示しませんでした。"Clear-History -id 3" のように正確な履歴 ID を指定すると、次のようなエラーが表示されます。

Clear-History : Cannot locate history for Id 3.

コマンド3番が画面に表示されても

どのように解決するのですか?

tl;dr

  • があります。 クリアすべき履歴 :

    • PowerShell独自の( Clear-History )
    • さらに、コンソール(端末)において、その PSReadLine モジュールで、PowerShell v5+ ではデフォルトでコマンドライン編集に使用される ( [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() )
  • のバージョン1.2以降では PSReadLine (検証は Get-Module PSReadLine ) を押す Alt+F7 は実行する を実行します。 であり、したがって を完全にクリアします。 セッション中 履歴 .

    • しかし はそうです。 ではない をクリアします。 保存される これまで蓄積された履歴 であるため、クリアされたセッションの履歴も 再浮上する となります。

    • をクリアするために 保存された 履歴 を指定する必要があります。 保存されたセッションが格納されているファイルを手動で削除します。 ( (Get-PSReadlineOption).HistorySavePath ) でラップされているように、後述するように Clear-SavedHistory 関数によってラップされます。


補完する CB.の有用な回答 JVimesさんの参考になる回答 :

  • PowerShell 独自の履歴メカニズム ( Get-History , Clear-History ) は ホスト非依存 であり、それがなぜ - 少し意外なことに - をクリアする必要があります。 ホスト のコマンド履歴を消去する必要があります。 個別に .

  • については コンソールホスト自身の履歴機能 :

    • doskey -スタイル履歴機能 モジュールの前に PSReadline がPowerShellに同梱されていました(下記参照)。

      • があります。 no 保存された 歴史 - の間だけ履歴が保存されます。 現在 セッションの間のみ保存されます。
      • Alt+F7 はコンソールの履歴をクリアするために使用されなければなりません。 で、それを行う (明白な) プログラム的な方法はなく、( cmd.exe コンソールウィンドウでは doskey /reinstall を使うこともできますが、PSではうまくいきません)。
      • CB.の回答 は、このキーボードの組み合わせをシミュレートする方法を示しています; 覚えておいてください: これは に加えて Clear-History .
    • この PSReadline モジュールは Windows 10 上の PowerShell v5 および v5.1 に付属しており、Windows Server 2016 にも同梱される予定です。 と共に出荷され、また、クロスプラットフォームの パワーシェル (コア) v7+ 版; それは を置き換えます。 doskey -スタイルの行編集とコマンド履歴機能をより洗練された機能で置き換えます。 また、古いWindows版/PS版(>= v3)のバージョンに後付けすることも可能で、それには PowerShell ギャラリー (PSv3、PSv4では、最初に PowerShellGet ).

      • コマンド 履歴は現在 セッションを越えて保存されます。 また、ファイル内の

        (Get-PSReadlineOption).HistorySavePath .
      • [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() をクリアするために使用することができます。 現在の セッションの履歴 (ただし、v1.2+ ではさらに Alt+F7 で現在の履歴を対話的に消去します)。
        • 注意事項 : で PSReadline のデフォルトの履歴保存スタイル。 SaveIncrementally , 機密性の高いコマンドはすでに保存されています。 を呼び出すまでに [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() そして が再表示されます。 次に セッション .
        • これを処理する唯一の方法は 保存された履歴ファイルを削除する で示されるように JVimesの回答 というものですが、しかし は必ず全歴史を消し去ります。 .
        • IF を呼び出すようにプロファイルをセットアップした場合 Set-PSReadlineOption -HistorySaveStyle SaveAtExit を呼び出すように設定されている場合 - この設定はそれ自体では明らかに固定されません - あなたは べきです。 を呼び出すだけで済ませることができるはずです。 [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() を呼び出すだけで済むはずです (さらに Clear-History を追加)、保存された履歴ファイルを削除することなく、以前のセッションから保存された履歴を失うことはありません。 しかし、v2.1.0 (この記事を書いている時点の最新版) の時点で SaveAtExit は壊れました。 - は履歴が全く保存されません。 https://github.com/lzybkr/PSReadLine/issues/262

以下は advanced function は、コマンド履歴を消去するのに必要なすべてのコマンド (PowerShell 自体とコンソールの両方) をバンドルしています。 doskey -スタイルと 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

  }

}