В старой пословице говорится: «Те, кто не помнят своей истории, обречены повторять ее». Однако в случае Windows PowerShell надо повторять историю, поэтому ее надо помнить точно. Windows PowerShell автоматически запоминает недавно выполненные команды, храня их в буфере (или истории), поэтому их можно легко «вспомнить» и выполнить снова.
Исторический выбор
При использовании консоли Windows PowerShell вы на самом деле работаете с двумя видами истории команд. Они совершенно независимы и никак не связаны друг с другом.
Первый вид истории — буфер команд, с которым вы наверняка знакомы. Он отображается при нажатии стрелки вверх для возвращения к ранее выполненной команде. Можно также нажать F7, чтобы получить меню с перечнем ранее выполненных команд. В меню можно стрелками выбрать нужную команду и нажать Enter, при этом команда будет выполнена.
По умолчанию буфер комадной строки хранит как минимум 50 команд. Можно изменять это значение, редактируя свойства самого окна консоли. Щелкните кнопку оконного меню и выберите Properties. Изменить размер буфера в поле «Command History buffer size» на вкладке Options.
В сущности, история команд самой оболочки Windows PowerShell отдельна. Она обслуживается приложением, поддерживающим консольный сеанс. Windows PowerShell даже не знает о ее существовании.
История, которую можно использовать
История, поддерживаемая самой Windows PowerShell, более полезна. Выполните команду Get-Command –noun history, чтобы увидеть четыре командлета, которые работают с расширенным журналом истории:
- Add-History
- Clear-History
- Get-History
- Invoke-Historyя
Есть также встроенная переменная: $MaximumHistoryCount. Она задает размер внутреннего буфера команд Windows PowerShell. По умолчанию эта переменная равна 64. Если нужно изменить ее, просто присвойте ей новое значение. Любые изменения будут сохраняться только на протяжении активного сеанса. Если изменения должны сохраняться дольше, добавьте в свой сценарий профиля примерно такое:
$MaximumHistoryCount = 100
Обычно это добавляют в файл [My]Documents\WindowsPowerShell\profile.ps1, который является одним из четырех автоматически выполняемых сценариев профиля, которые ищет оболочка.
Основное внимание мы уделим Get-History — самому полезному командлету из перечисленных четырех. Она создает объекты типа HistoryInfo. У этих объектов четыре свойства, которые наверняка покажутся вам интересными:
- CommandLine — фактически выполненная командная строка
- StartExecutionTime —- время начала выполнения команды
- EndExecutionTime — время завершения выполнения команды
- ExecutionStatus — состояние команды после завершения, например «Completed» или «Stopped»
Совместное использование этих объектов с другими командами Windows PowerShell — вот когда начинаются крутые вещи. Допустим, к примеру, что вы открыли совершенно новое окно оболочки и запустили несколько команд в рамках выполнения сложной задачи. Если нужно превратить эти команды в сценарий, чтобы выполнять их многократно, сделайте следующее:
Get-History | Select –Expand CommandLine | Out-File script.ps1
Хитрость здесь в параметре –ExpandProperty команды Select-Object. Он заставляет Select-Object возвращать содержимое только указанного свойства. В данном случае это свойство CommandLine объектов HistoryInfo. Они содержат текст только что выполненных команд. Затем можно отредактировать полученный файл Script.ps1 в Windows PowerShell ISE или другом редакторе сценариев, чтобы скорректировать команды, преобразовать жестко закодированные значения в параметры, удалить ненужные команды и т. п.
Допустим, вы выполнили указанный прием и получили такой файл Script.ps1:
Import-Module ActiveDirectory
Import-CSV users.csv
Import-CSV users.csv | New-ADUser –path "ou=sales,dc=company,dc=com"
Это очень короткий пример, но интерактивно выполняя команды, вы можете убедиться, что они работают — одна за одной. Вы наверняка увидели, что вторая команда это всего лишь проверочный импорт CSV-файла. Она просто проверяет, что в файле есть нужные данные. Дальше можно подчистить сценарий и добавить параметры:
Param(
[string]$filename = &(Read-Host "Specify input CSV filename"),
[string]$path = "cn=Users,dc=company,dc=com"
)
Import-Module ActiveDirectory
Import-CSV $filename | New-ADUser –path $path
Команда «проверочного импорта» и добавленный параметр получают имя CSV-файла и целевого подразделения (OU). Это лучше, чем оставлять эти значения в коде. Позаботьтесь, чтобы при выполнении этого сценария выдавался запрос на ввод имени файла, если человек, запускающий сценарий, забыл его указать (это ужасный способ информирования пользователя — расширенная функция позволит это сделать аккуратнее и более стандартным способом). Для второго параметра задайте значение по умолчанию, которое будет использоваться, если при запуске сценария не будет указано другое значение.
Это простой способ выполнить процесс, который вы уже прошли раньше, и быстро превратить его в повторяемую последовательность действий, которую могут даже использовать другие люди.
Еще парочка хитростей истории
Возможность «получить» историю командной строки позволяет выполнять другие хитрые трюки.
- Выполните Run Get-History | Export-CliXMLfilename, чтобы экспортировать команды в XML-файл. Отправьте этот XML-файл коллегам и они смогут быстро повторить команды, выполнив Import-CliXMLfilename | Invoke-History.
- Используйте свойства StartExecutionTime и EndExecutionTime для определения времени выполнения команды. Например, так:
get-history | select commandline,executionstatus,startexecutiontime,endexecutiontime,@{n='ExecutionDuration';e={$_.EndExecutionTime - $_.StartExecutionTime}} - Быстро находите прошлые команды без необходимости нажимать стрелку вверх. Например, если вы знаете, что вы выполняли команду со словом «Select», попробуйте найти ее так:
get-history | where { $_.CommandLine -like '*select*' }
Как всегда, Windows PowerShell обрабатывает все как объекты, а не массив текста. Это делает процесс поиска и фильтрации намного более осмысленным, если нужно просмотреть текстовый файл журнала или что-то такое же громоздкое.