Перейти к основному содержимому

Шпаргалка по командам PowerShell

··2931 слово·14 минут

Дисклеймер

Статья не претендует на статус полного руководства по PowerShell; для этих целей есть официальные ресурсы Microsoft и множество других источников. Я описываю только те команды и приёмы, которые использую сам.

Я излагаю материал в силу своего понимания и знаний. Никто не застрахован от ошибок.

Вместо вступления

Я всю жизнь пользуюсь Windows, но с пятнадцати лет так или иначе администрирую серверы с OS Linux (преимущественно Debian и Ubuntu).

И так получилось, что команды Bash мне намного привычнее, чем команды Cmd или PowerShell.

Однако, даже на Windows чаще удобнее воспользоваться cli-инструментами и не искать “супер крутую бесплатную программу без регистрации и СМС”.

В Windows у нас есть два варианта: морально устаревший cmd (just IMHO), а также развивающийся и навороченный PowerShell. О нём, а точнее о его командах, и пойдёт речь.

Для некоторых команд я приведу аналогичную строку для Bash. Для других такого аналога не будет, если объяснение различий и нюансов потребует слишком много текста.

Статья должна оставаться удобной шпаргалкой и не разрастаться в полноценное руководство по переучиванию с Bash на PowerShell.

Для некоторых команд я приведу официальные алиасы (я сам, как и вы наверное, не люблю нажимать лишние кнопки на клавиатуре там, где этого можно не делать). Для других команд вы сможете сделать свои алиасы при необходимости.

Я сознательно оформляю шпаргалку в виде списка и избегаю таблиц. Таблицы в Markdown нестабильны и к тому же неудобны для редактирования со скринридером.

Немного теории

PowerShell - объектно-ориентированная оболочка и объектно-ориентированный скриптовый язык, а это значит, что результатом команды часто является объект со свойствами и даже методами, а не сырой текст, как в Bash или Zsh.

Чтобы посмотреть структуру объекта, который возвращает та или иная команда PowerShell, используйте вот такую конструкцию:

<command> | Get-Member

Команда выведет список всех свойств и методов объекта, возвращаемого командой до конвеера (вертикальной черты).

Например, команда Get-Process без параметров возвращает информацию обо всех процессах в системе.

Get-Process | Get-Member

Эта команда выведет список всех свойств и методов объекта с информацией о процессе в виде таблицы. Важно: в выводе команды может показаться, что через трубку (вертикальную черту) передался только один объект, а не массив всех объектов процессов. Это не так: просто элементы коллекции передаются следующей команде по одному.

Таблицы не всегда удобны для чтения со скринридером, поэтому результат можно направить в команду форматирования в виде списка:

Get-Process | Get-Member | Format-List

На выходе получим уже плоское представление в виде списка, которое удобнее читать со скринридером.

Или можно короче, используя официальные алиасы:

Get-Process | gm | fl

Файлы и директории

Команды для работы с файлами и директориями.

Навигация

Команды навигации по файловой системе.

  • Get-Location - получить путь к текущей рабочей директории.

    Официальные алиасы: pwd, gl.

    Команда возвращает объект, а не строку. Для получения чистой строки используйте (pwd).Path или $PWD.Path.

  • Get-ChildItem - вывести список файлов и папок в рабочей директории.

    Аналог ls в Bash.

    Официальные алиасы: ls, dir, gci.

    По умолчанию выводится таблица. Чтобы вывести только имена (аналогично ls -1) списком, можно использовать Get-ChildItem | Select-Object -ExpandProperty Name, что очень длинно.

    Короче можно так: (ls).Name, ls -Name, или более грамотно с точки зрения PowerShell ls | select -Expand Name.

    Чтобы отобразить скрытые и системные файлы и папки (аналог ls -a в Linux): ls -Force.

    Как и в Linux, передав относительный или абсолютный путь команде ls, можно вывести список не только для рабочей (текущей) директории.

    Можно вывести только файлы ls -File или только директории ls -Directory.

  • Set-Location - сменить рабочую директорию.

    Аналог cd в Bash.

    Официальные алиасы: cd, sl, chdir.

    Поведение почти аналогично тому, что в Linux: cd .. переходит на уровень выше, cd - переходит в предыдущую директорию.

    Важно: PowerShell запоминает рабочую директорию отдельно для каждого диска. Для точного перехода в корень диска лучше использовать cd C:/ или cd C:\.

    Для перехода в корень текущего диска используйте cd \, для перехода в домашнюю директорию - cd ~.

  • Push-Location - сменить рабочую директорию и запомнить текущую в стеке.

    Полный аналог pushd в Bash.

    Официальные алиасы: pushd.

  • Pop-Location - сменить рабочую директорию на ту, что сохранена на вершине стека.

    Полный аналог popd в Bash.

    Официальные алиасы: popd.

  • Get-Location -Stack - получить стек директорий, сохранённых с помощью Push-Location.

    Также работает pwd -Stack.

  • Get-PSDrive - посмотреть список доступных дисков PowerShell.

    Это не только диски C:, D:, но и другие локации, например Env: как псевдодиск для переменных окружения, HKCU: - как отображение конкретной ветви реестра.

    Официально такие диски называются дисками провайдеров PowerShell.

  • Get-PSProvider - получить список доступных провайдеров PowerShell.

    Похоже на предыдущую команду Get-PSDrive, но выводит список провайдеров, а не их точек входа.

    Существуют стандартные провайдеры, доступные в каждой системе, а также провайдеры, добавляемые модулями PowerShell.

Работа с файлами и директориями

Команды для создания, изменения и удаления файлов и директорий.

  • New-Item - создать файл (или директорию см. ниже).

    Аналог touch в Bash.

    Официальные алиасы: ni, mkdir (для директории).

    Для создания директории используется ni -ItemType Directory или более привычный официальный алиас mkdir.

  • Copy-Item - копировать файл или директорию.

    Аналог cp в Bash.

    Официальные алиасы: cp, cpi, copy.

    Для копирования директории, как и в Linux, нужен флаг рекурсивного копирования: cp -Recurse source-folder dest-folder.

  • Move-Item - переместить файл или директорию.

    Аналог mv в Bash.

    Официальные алиасы: mv, move, mi.

    Как и в Linux, для перемещения директории флаг рекурсивности не нужен.

  • Rename-Item - переименовать файл или директорию.

    Аналог в Bash: mv.

    Официальные алиасы: ren, rni.

  • Remove-Item - удалить файл или директорию.

    Аналог rm в Bash.

    Официальные алиасы: rm, del, erase, ri.

    Для удаления директорий нужен флаг рекурсивности: rm some-folder -Recurse.

Работа с содержимым файла

Команды для работы с содержимым файлов: записать в файл, прочитать из файла, очистить файл, добавить в конец файла.

  • Get-Content - прочитать содержимое файла.

    Аналог cat.

    Алиасы: gc, cat, type.

    Важно: обычный Get-Content передаёт в конвеер каждую строку отдельным объектом. Если важно получить весь файл целиком, используйте cat -Raw file.txt.

    Также, Get-Content заменяет в PowerShell команды head и tail: cat file.txt -Head 10, cat file.txt -Tail 5.

    Ещё Get-Content имеет функцию tail -f: Get-Content log.txt -Tail 5 -Wait.

  • Set-Content - перезаписывает содержимое в файл, стирая старое содержимое.

    Аналог в Bash: перенаправление в файл с помощью >.

    Set-Content может принимать текст и через конвеер, как в виде сырого текста, так и в виде массива строк.

    Для явного указания кодировки можно использовать Set-Content file.txt "some text" -Encoding Utf8NoBom.

    Также Set-Content принимает объекты через конвеер, но для читаемого форматированного содержимого лучше использовать специальные команды записи форматированного содержимого в файл.

  • Add-Content - добавляет содержимое в конец файла, не стирая старое содержимое.

    Аналог в Bash: перенаправление в файл с помощью >>.

    Команда принимает содержимое и через конвеер (аналогично Set-Content).

    Для явного указания кодировки можно использовать Set-Content file.txt "some text" -Encoding Utf8NoBom.

    Аналогично и поведение касательно объектов, переданных через конвеер.

  • Clear-Content - очищает содержимое файла.

    Аналоги в Bash: : > file.txt, truncate -s 0 file.txt.

    Официальные алиасы: clc.

    Эта команда не удаляет файл, но полностью стирает его содержимое.

ПРимечания

Не используйте Set-Content, Add-Content, Get-Content для двоичных файлов без специальных параметров.

Поиск

КОманды поиска файлов и папок, а также поиска и фильтрации содержимого файлов.

  • ls -Recurse -Filter *.txt - найти рекурсивно все файлы и папки, подходящие под glob “*.txt”.

    Аналог в Bash: find . -name "*.txt".

    Без параметра -Recurse команда будет искать только в текущей директориии, не обходя рекурсивно дочерние.

  • Select-String -Path *.log -Pattern "error" - найти и вывести во всех файлах “*.log” строки, подходящие под паттерн “error”.

    Аналог grep "error" *.log в Bash.

    Официальные алиасы: sls.

    По умолчанию -Pattern - это регулярное выражение. Для простого поиска по подстроке используйте параметр -SimpleMatch.

    По умолчанию поиск не чувствителен к регистру. Для чувствительного к регистру поиска используйте параметр -CaseSensitive.

Магия PowerShell: работа с объектами

PowerShell работает с объектами, и было бы упущением не использовать открывающиеся в связи с этим возможности.

Аналогов в Bash нет, поэтому и формат списка команд немного поменяется: каждой команде я выделяю отдельный заголовок.

Все команды для работы с объектами мы будем тестировать на выводе команды Get-Process, которая возвращает список запущенных в системе процессов.

Where-Object - фильтрация объектов

Аналогично grep, find, awk, но по свойствам объектов.

Алиасы: where или просто знак вопроса ?, что менее читаемо, но и буквы экономит.

Например: Get-Process | where CPU -gt 10.

КОманда выше вернёт только объекты процессов, у которых свойство CPU имеет значение большее, чем 10.

Подробный разбор:

  • Get-Process возвращает коллекцию объектов, каждый из которых описывает один процесс в операционной системе.
  • where фильтрует объекты по условию и пропускает в конвеер дальше (или на экран) только те, которые подошли под условие.
  • CPU - одно из свойств объекта процесса.
  • -gt 10 - условие: “значение указанного свойства должно быть строго больше 10”.

Ещё несколько примеров. Если вы дочитали до этого места, назначения этих команд должны быть вам понятны.

  • ls | where Extension -eq ".txt"
  • ls | where Length -gt 1MB
  • ls | where LastWriteTime -gt (Get-Date).AddDays(-7)
  • Get-Service | where Status -eq "Running"

Select-Object - выбрать поля объекта

Примерно аналогично cut, но по свойствам объектов.

Алиас: select.

Например: Get-Process | select Name, Id, CPU.

Команда выше выберет из каждого объекта процесса только поля Name, Id, CPU и создаст новые объекты только с этими полями.

Если вывод направить в конвеер, то следующая команда не получит ничего лишнего, только указанные свойства. При выводе на экран получится красивая таблица.

А ещё можно так: Get-Process | select -Expand Name.

Параметр -Expand или его полная форма -ExpandProperty позволяет отдать не объекты с единственным полем Name, а коллекцию строк, уже без объектов вовсе.

Sort-Object - сортировка объектов

Наверное аналогично sort в Linux, но всё же далеко по смыслу, так как работает с объектами. Всё же это ближе к сортировкам объектов в массиве в языках программирования.

Алиас: sort.

Например: Get-Process | sort CPU.

Команда выше выведет список процессов, отсортированный по возрастанию значения свойства CPU.

Для сортировки по убыванию (актуально для CPU) используйте Get-Process | sort CPU -Descending.

Вот ещё несколько примеров из реальной практики:

  • ls | sort Length -Descending
  • ls | sort LastWriteTime -Descending
  • Get-Service | sort Status, Name

Как видите, сортировать можно и по нескольким свойствам. Тогда сначала объекты будут отсортированы по первому свойству (в нашем примере: по статусу), а затем, уже в рамках этой сортировки - по имени.

Measure-Object - посчитать

Прямого единственного аналога из Linux не придумал.

Алиас: measure.

Посчитать можно многое и по-разному, так что примеры расскажут о команде лучше слов.

ls | Measure-Object - посчитать количество файлов и папок в текущей директории.

ls -File | Measure-Object Length -Sum - посчитать суммарный размер файлов в текущей директории (это не полный аналог du).

Полный аналог du выглядит вот так:

ls -Recurse -File | measure Length -Sum.

А ещё measure умеет много других полезных показателей.

Например команда ls -Recurse -File | measure Length -Sum -Average -Minimum -Maximum -StandardDeviation, запущенная в корне моего Dev Drive, очень долго думала и показала такой вывод:

Count             : 328156
Average           : 109012,413608162
Sum               : 35773077600
Maximum           : 1576629248
Minimum           : 0
StandardDeviation : 5101472,38548372
Property          : Length

Это очевидно круче, чем wc в Linux.

Group-Object - сгруппировать

Аналогично sort | uniq -c В Linux, но опять же по свойству объекта.

Например: ls -File | group Extension.

Команда выше выведет список файлов, сгруппированный по расширениям, показав ещё и количество файлов с таким расширением.

На мой взгляд, подобное нужно гораздо реже, чем остальные команды работы с объектами, но пригодиться может.

Ещё пример: вывести службы Windows, сгруппированные по статусу. Тут мне в первую очередь было интересно посмотреть их количество.

Get-Service | group Status

Foreach-Object - выполнить действие для каждого объекта

Алиас: знак процента %.

Это аналог цикла foreach в некоторых языках программирования или нечто аналогичное for item in collection: ... в Python.

Здесь важно сказать про переменную $_, которая представляет текущий объект в подобных циклах.

Например, вывести красивую таблицу вида “имя файла и размер” можно так: ls *.txt | % { "File: $($_.Name), Size: $($_.Length)" }.

Магия на примерах

  • Найти и вывести 10 самых больших файлов, начиная с текущей директории рекурсивно: ls -Recurse -File | sort Length -Descending | select -First 10 FullName, Length.
  • Все .log файлы больше 10 мб: ls -Recurse -File -Filter *.log | where Length -gt 10MB | select FullName, Length.
  • Посчитать общий размер mp3 файлов: ls -Recurse -File -Filter *.mp3 | measure Length -Sum.
  • Найти топ 10 самых тяжёлых по CPU процессов и вывести только имя процесса, его PID и потребление CPU: Get-Process | where CPU -gt 1 | sort CPU -Descending | select -First 10 Name, Id, CPU.

Форматирование для вывода на экран

Наверняка вы уже пробовали запускать команды из этой статьи и видели, что вывод получается красивым, форматированным.

Этим форматированием можно управлять. Я даже упоминал об этом во вступлении.

  • Format-Table или ft - вывести данные на экран в виде таблицы.

    Это менее удобно для чтения со скринридером, но полезно для визуального просмотра или для красивых скриншотов.

  • Format-List или fl - вывести данные в виде списка.

    Это визуально менее красиво, занимает намного больше строк, но очень удобно для навигации и изучения при помощи скринридера.

  • Format-Wide или fw - вывод данных в несколько столбцов (примерно как команда ls в Linux размещает имена в несколько столбцов).

  • Format-Custom или fc - кастомное форматирование.

    Внимание! Без дополнительных параметров даёт крайне “шумный” вывод и не рекомендуется к использованию.

    За то позволяет глубже изучать свойства и методы объектов, вложенных в том числе.

Как превратить объекты в текст

ДЛя этого существуют две команды: Out-String и Out-File.

Как понятно из их названий, первая превращает текст в строку, и дальше по конвееру или на экран попадает уже не объект, а строка.

Вторая же действует аналогично, но позволяет сохранить данные в файл.

Для перенаправления данных в файл также работают привычные по Bash операторы > и >>, но их поведение не всегда одинаково и предсказуемо, поэтому Out-String и Out-File предпочтительнее.

Также, существует команда Tee-Object (алиас tee), которая одновременно сохраняет текст в файл и выводит его на экран (либо передаёт дальше в конвеер).

работа с данными: экспорт и импорт

csv

ДАнные можно экспортировать в csv:

Get-Process | Export-Csv processes.csv -NoTypeInformation.

Или дополнить существующий csv, не стирая старые данные:

Get-Process | Export-Csv processes.csv -NoTypeInformation -Append.

csv можно не только экспортировать, но и импортировать:

Import-Csv processes.csv.

После импорта строки csv становятся объектами PowerShell, и с ними можно работать уже привычными способами:

Import-Csv processes.csv | Where-Object Name -eq "pwsh".

Также, можно конвертировать в csv и обратно без сохранения в файл:

Get-Process | Select-Object Name, Id | ConvertTo-Csv -NoTypeInformation

И обратно:

$text | ConvertFrom-Csv.

json

Для json почему-то не существует команд для экспорта в файл и импорта из файла. Однако вот так уже можно:

Get-Process | Select-Object Name, Id, CPU | ConvertTo-Json | Set-Content processes.json -Encoding utf8

И так тоже можно (прочитать обратно):

Get-Content data.json -Raw | ConvertFrom-Json.

Для конвертации в json может пригодиться параметр -Depth. Без него у сложных объектов вложенные свойства могут оказаться обрезанными.

Для чтения json из файла почти всегда предпочтительнее использовать параметр -Raw у Get-Content, чтобы json прочитался и передался в конвеер одним текстом, а не коллекцией отдельных строк.

Экспорт в html

Да-да, я сам удивился, когда в списке команд нашёл это, но можно экспортировать данные в виде таблицы сразу в html.

Get-Process | Select-Object Name, Id, CPU | ConvertTo-Html -Title "Processes" | Set-Content processes.html -Encoding utf8

Таблица получается простая, без оформления и украшений, но для чтения скринридером или сухих отчётов часто и этого достаточно.

Импорт пар ключ-значение

Это не полноценный .env парсер, но файл с содержимым вида

firstName=Kirill
lastName=Belousov
role=developer

вполне подходит.

То есть можно сохранить написанное выше как файл data.txt и прочитать вот так:

$data = Get-Content -Raw data.txt | ConvertFrom-StringData.

На выходе в переменную $data будет сохранена хеш-таблица с ключами слева от = и значениями справа.

Работа с процессами

Команды для взаимодействия с процессами в операционной системе.

Прочитав часть статьи выше, вы уже познакомились с базовыми принципами. Поэтому дальше описания будут короче, с меньшим числом примеров.

Помните, что Get-Command - ваш лучший друг и аналог man.

Также, помните, что как и в Linux, доступность информации о некоторых процессах и возможности некоторых команд могут зависеть от полученных привилегий.

  • Получить список всех запущенных в системе процессов: Get-Process, ps или gps.

    Команда принимает позиционный аргумент, с помощью которого можно находить процессы по заданной подстроке. Также, можно передать точное имя процесса с помощью параметра -Name или запросить информацию о процессе с конкретным PID при помощи параметра -Id.

  • Запустить новый процесс: Start-Process или start.

    При помощи параметра -Wait можно дождаться завершения процесса, а при помощи -ArgumentList - передать список аргументов для вызываемого исполняемого файла.

    Чтобы запустить процесс от имени администратора, используйте конструкцию Start-Process exe_name -Verb RunAs.

  • Остановить (убить) процесс: Stop-Process, kill или spps.

    Команда останавливает процесс по PID (kill -Id <PID>) или останавливает один или несколько процессов по имени (kill -Name <exe_name>).

    Также, команда принимает объекты процессов, например полученные через Get-Process, через конвеер или через переменную при помощи параметра -InputObject.

  • Ждать завершения процесса: Wait-Process.

    Объект процесса можно передать через конвеер, либо указать процесс по -Name или по -Id, как и в других командах.

    Можно задать таймаут ожидания: Wait-Process -Name notepad -Timeout 10.

Полезные свойства объекта процесса

Все свойства вполне самодокументированы своими именами и не требуют дополнительных пояснений. За это я и люблю PowerShell.

  • Id
  • ProcessName
  • Path
  • CPU
  • WorkingSet
  • StartTime
  • HasExited
  • MainWindowTitle

Примечание

Чтобы одна команда для работы с процессами передала объект дальше в другую команду по конвееру, используйте параметр -PassThru.

Например, возможна такая конструкция:

Start-Process notepad -PassThru | Wait-Process -Timeout 5 -PassThru | Stop-Process.

Команда выше запустит блокнот, подождёт 5 секунд и закроет блокнот.

Буфер обмена

Да, в PowerShell можно взаимодействовать с буфером обмена Windows. Правда работать можно только с текстом, но и этого часто бывает достаточно.

Основных команд всего две:

  • Get-Clipboard - получить содержимое буфера обмена (только текст).
  • Set-Clipboard - записать текст в буфер обмена.

У второй команды также есть параметр -Append, который позволяет не перезаписать, а дополнить содержимое буфера обмена.

Обе команды конечно же работают через конвеер (Get-Process | Out-String | Set-Clipboard, $params = Get-Clipboard | ConvertFrom-StringData).

Вместо заключения

Не уверен, что эту статью можно когда-нибудь закончить. Я постоянно пополняю её новыми командами, уточнениями, примечаниями по мере того, как сам изучаю особенности оболочки и скриптового языка PowerShell.

Надеюсь, для вас эта шпаргалка окажется полезной.

Кирилл Белоусов
Автор
Кирилл Белоусов
Также известен как cyrmax. Пишу код, тестирую, автоматизирую инфраструктуру и помогаю делать цифровые продукты доступнее.