Історія команд в сеансі PowerShell

Спочатку Windows PowerShell (як і командний рядок cmd) зберігає історію виконаних команд тільки в поточній сесії PowerShell, при закритті вікна консолі PowerShell або перезавантаження комп'ютера, історія команд PowerShell які ви набирали ніде не зберігається. У порівнянні з тією ж bash це є суттєвим недоліком. У версії PowerShell v5, представленої в Windows 10 цей недолік був виправлений.

зміст:

  • Історія команд в PowerShell 5.0, модуль PSReadLine
  • Очищення історії команд в PowerShell
  • Імпорт історії команд PowerShell в іншу сесію

Історія команд в PowerShell 5.0, модуль PSReadLine

Припустимо, ви набрали і виконали якусь складну команду PowerShell. У Windows 10 і Windows Server 2016 навіть після перезавантаження комп'ютера ви можете відкрити нову сесію PowerShell і натиснути клавішу зі стрілкою вгору. На екрані повинна відобразити остання введена вами команда. Якщо продовжити натиснути клавішу "вгору" - ви побачите всі команди, виконані раніше. Таким чином за допомогою клавіш "вгору" і "вниз" ви можете прокручувати історію команд та повторно виконувати раніше набрані команди.

У більш ранніх версіях PowerShell історія команд в поточній сесії не зберігалася після її закриття. За допомогою клавіш вгору / вниз ви можете перегортати історію команд поточної сесії або вивести їх все відразу за допомогою командлета Get-History.

Можна вивести більш детальну інформацію про раніше виконаних командах, в тому числі статусу і часу запуску / закінчення виконання команди:
Get-History | Format-List -Property *

Оболонка PowerShell в Windows 10 за замовчуванням запам'ятовує останні 4096 команд, які зберігаються в текстовому файлі, розташованому в профілі кожного користувача

% Userprofile% \ AppData \ Roaming \ Microsoft \ Windows \ PowerShell \ PSReadline \ ConsoleHost_history.txt

. Історія ведеться окремо для консолі PowerShell, окремо для ISE.

Запущена команда PowerShell потрапляє в історію тільки після закінчення її виконання. Якщо команда PoSh вимагає тривалого часу на виконання, ви побачите її в історії команд тільки по її завершенні.

У тому випадку, якщо ви не хочете перегортати всю історію команд PowerShell, ви можете виконати пошук по історії команд за допомогою комбінації клавіш CTRL+R (Пошук в зворотному напрямку) і CTRL+S (Пошук вперед). Натисніть клавіші і почніть вводити частину команди, яку ви хочете знайти в раніше виконаних командах. В історії команд буде виконаний пошук введеного тексту на будь-якій позиції (на відміну від пошуку в консолі PowerShell по F8 або Shift + F8, які шукають збіги тільки з початку рядка) і підсвічений підходящий варіант.

Примітка. Функціонал ведення історії команд в PowerShell 5 вбудований не в сам Windows Management Framework, а заснований на сторонньому модулі PSReadLine, істотно розширюють функціонал консолі PowerShell. У Windows 10 він знаходиться в каталозі C: \ Program Files\ WindowsPowerShell\ Modules\ PSReadline і автоматично імпортується при старті консолі PowerShell. PSReadLine здійснює підсвічування синтаксису в консолі, відповідає за можливість використання виділення тексту мишкою і його копіювання / вставку за допомогою CTRL + C і CTRL + V. PSReadLine не входить до складу окремо встановлюється PowerShell 5 для попередніх версій Windows. Таким чином, якщо ви захочете використовувати функціонал ведення історії виконаних команд PowerShell в попередніх версіях ОС (Windows 7 / 8.1 / Windows Server 2008 / R2 / 2012R2) крім установки Windows Management Framework 5.1, вам знадобиться встановити модуль PSReadLine за допомогою менеджера пакетів PackageManagement (раніше OneGet) з оналйн сховища командою:

Install-Module PSReadLine

Повний список функцій модуля PSReadLine для управління історією виконання команд в PowerShell і прив'язаних до них клавішах можна вивести командою:

Get-PSReadlineKeyHandler | ? $ _. Function -like '* hist *'

Key Function Description
---       --------             -----------
Key Function Description
---       --------                -----------
UpArrow PreviousHistory Замінити введені дані попереднім елементом журналу
DownArrow NextHistory Замінити введені дані в такий елементом журналу
Ctrl + R ReverseSearchHistory Виконати інтерактивний пошук по журналу в зворотному напрямку
Ctrl + S ForwardSearchHistory Виконати інтерактивний пошук по журналу в напрямку вперед
Alt + F7 ClearHistory Видалити всі елементи з журналу командного рядка (не з журналу PowerShell)
F8 HistorySearchBackward Шукати попередній елемент журналу, який починається з поточного введення, наприклад P ...
Shift + F8 HistorySearchForward Шукати наступний елемент журналу, який починається з поточного введення, наприклад Ne ...
Unbound ViSearchHistoryBackward Запускає новий пошук по журналу в напрямку назад.
Unbound BeginningOfHistory Перейти до першого елементу журналу
Unbound EndOfHistory Перейти до останнього елемента (поточний введення) в журналі

Налаштування історії команд виконується за допомогою командлетів Get-PSReadlineOption і Set-PSReadlineOption. Поточні параметри можна отримати за допомогою такої конструкції:

Get-PSReadlineOption | select HistoryNoDuplicates, MaximumHistoryCount, HistorySearchCursorMovesToEnd, HistorySearchCaseSensitive, HistorySavePath, HistorySaveStyle

Нам можуть бути цікаві настройки наступних параметрів:

  • HistoryNoDuplicates - чи потрібно зберігати в історії PowerShell однакові команди;
  • MaximumHistoryCount - максимальне число збережених команд (за замовчуванням зберігаються 4096 команд);
  • HistorySearchCursorMovesToEnd - чи потрібно переходити в кінець команди при пошуку;
  • HistorySearchCaseSensitive - чи потрібно враховувати регістр при виконанні пошуку;
  • HistorySavePath - шлях до текстового файлу, в який зберігається історія команд PowerShell;
  • HistorySaveStyle - особливості збереження команд:
    • SaveIncrementally - команди зберігаються при виконанні (за замовчуванням)
    • SaveAtExit - збереження історії при закритті консолі
    • SaveNothing - відключає ведення історії команд

Змінити настройки модуля PSReadLine можна за допомогою команди Set-PSReadlineOption, наприклад:

Set-PSReadlineOption -HistorySaveStyle SaveAtExit

Таким чином, можливість збереження історії виконаних команд в PowerShell 5.0 - це ще один аргумент відмови від cmd на користь консолі PoSh.

Очищення історії команд в PowerShell

Як ми розповіли вище, модуль PSReadline зберігає всі консольні команди PowerShell в текстовий файл. Однак в деяких випадках адміністратору доводиться вводити в консолі PowerShell різну конфіденційну інформацію (учеткі, паролі, адреси, персональні дані і т.д.). Таким чином інший адміністратор сервера або атакуючий може отримати доступ до даних в текстовому файлі. З метою безпеки вам може знадобитися очистити журнал виконаних команд PowerShell або зовсім відключити історію команд.

командлет Clear-History використовувати для очищення історії команд не можна, тому що він очищає тільки список попередніх команд, які виводить командлет Get-History.

Щоб видалити історію попередніх команд PoSh, потрібно видалити файл, в який вони зберігаються. Найпростіше це зробити командою:

Remove-Item (Get-PSReadlineOption) .HistorySavePath

Після цього закрийте сесію PoSh:

Якщо потрібно повністю відключити збереження історії команд PoSh в текстовий файл, виконайте команду:

Set-PSReadlineOption -HistorySaveStyle SaveNothing

Імпорт історії команд PowerShell в іншу сесію

У деяких випадках буває зручно мати під рукою один і той ті список часто-використовуваних команд PowerShell на різних комп'ютерах. Ви можете експортувати поточну історію команд в xml файл і імпортувати їх на інших комп'ютерах. Це можна зробити, скопіювавши файл ConsoleHost_history.txt в профілі користувачів на потрібних комп'ютерах.

Також для експорту команд з поточної сесії в файл можна використовувати командлет Export-Clixml:

Get-History | Export-Clixml -Path c: \ ps \ commands_hist.xml

Для імпорту команд з файлу в сесію PoSh:

Add-History -InputObject (Import-Clixml -Path c: \ ps \ commands_hist.xml)

Для автоматичного імпорту команд в файл при завершенні сесії PoSh, можна прив'язати скрипт до події завершення сесії PoSh (!! Сесія обов'язково повинна завершуватися командної exit, а не простим закриттям вікна PoSh):

$ HistFile = Join-Path ([Environment] :: GetFolderPath ( 'UserProfile')) .ps_history
Register-EngineEvent PowerShell.Exiting -Action Get-History | Export-Clixml $ HistFile | out-null
if (Test-path $ HistFile) Import-Clixml $ HistFile | Add-History