Добро пожаловать обратно, хакеры!
При переходе с Bash на PowerShell люди часто сталкиваются с трудностями просто потому, что не знают, какие инструменты PowerShell служат эквивалентами и как ими пользоваться. Например, мне лично Bash нравится своей простой логикой. Если вам нужно извлечь только определённые строки из текстового файла, вы знаете, что можно вызвать cat и grep. Но когда вы пытаетесь ввести что-то подобное в PowerShell, часто возникает ощущение, будто вы упираетесь в стену. Вы знаете логику, вы знаете, что это должно быть всего одна строка, но всё равно не понимаете, как это сделать. Именно это мы и собираемся сегодня разобрать.
Эта статья дополняет книгу «Powershell for Hackers: Basics» и призвана продемонстрировать больше возможностей PowerShell, сопоставляя знакомые команды Bash с их эквивалентами в PowerShell. Если вы ещё не читали «Powershell for Hackers: Basics» , настоятельно рекомендуем начать с неё. Это руководство предназначено для тех, кто знаком с командной строкой Linux и хочет получить практические примеры для своих рабочих процессов в PowerShell.
PS > Write-Host (2,4,6,8,10,12) -Separator "->" -ForegroundColor DarkMagenta -BackgroundColor White
Этот фрагмент кода выведет последовательность чисел в скобках, добавит между ними символ -> , а также изменит цвет текста и фона. Для быстрого скрипта это необязательно, но для ежедневного отчёта может быть весьма полезно.
Если вам нужно что-то сравнить, в PowerShell есть полный набор операторов, знакомый любому, кто работал с Linux.
Если операторы сравнения и логические условия более-менее понятны, давайте рассмотрим очень простой, но практичный пример с типами данных. Предположим, мы хотим измерить среднее время ответа веб-сайта, например, google.com . Для этого нам нужно отправить несколько пингов и вычислить среднее значение. Вот короткий скрипт:
Write-Host `n "Waiting for test ..."<br>$Avg = 0<br>$Site = "www.google.com"<br>$PingSite = Test-Connection -Count 5 $Site<br>$Avg = ($PingSite | Measure-Object ResponseTime -Average)<br>$Calc = ($Avg.Average) -as [int]<br>Clear-Host<br>Write-Host "Average response time to $Site is $Calc ms"
Если не преобразовать значение в целое число, мы получим число с плавающей запятой, что не очень удобно для данной цели.
Это один из случаев, когда команда PowerShell на самом деле эффективнее классического ping в Linux. Командлет Test-Connection выводит структурированные объекты, которые уже содержат время ответа, статус и другие полезные свойства. Это означает, что вы можете передавать результаты непосредственно в инструменты, такие как Measure-Object , и выполнять с ними математические операции, не разбирая текст с помощью awk или grep. В Linux ping работает с текстом, поэтому для извлечения чисел часто требуются дополнительные команды. PowerShell пропускает этот шаг.
PS > Get-Alias
Псевдонимы могут даже указывать на программы. Например, создадим псевдоним для запуска калькулятора:
PS > Set-Alias -Name calc -Value calc.exe
Теперь ввод команды calc запустит калькулятор. Если вы хотите, чтобы ваш псевдоним представлял команду с параметрами, вам нужно обернуть его в функцию:
function AL01 { Test-Connection -Count 2 google.com }<br>Set-Alias ping AL01
Теперь при вводе команды ping будут выполнены два пинга на google.com . Чтобы удалить псевдоним, используйте:
PS > Remove-Item alias
ing
Обратите внимание: после закрытия PowerShell все созданные вами таким образом псевдонимы исчезнут. Чтобы сохранить их навсегда, необходимо сохранить их в своём профиле. В PowerShell существует четыре возможных профиля. Вы можете просмотреть их с помощью:
PS > $profile | Format-List -Force
Чтобы проверить, существуют ли они в вашей системе:
PS > $profile | Format-List -Force | ForEach-Object { Test-Path $_ }
Если результат — False, файл просто не существует. Вы можете создать его, например, по этому пути:
PS > notepad.exe C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1
И добавьте внутрь него свои псевдонимы:
function AL01 { Test-Connection -Count 2 google.com }<br>Set-Alias ping AL01
После сохранения и перезапуска PowerShell ваши псевдонимы загрузятся автоматически.
Важное замечание. По умолчанию Windows блокирует выполнение внешних скриптов. Это означает, что ваш файл профиля может быть проигнорирован. Чтобы проверить текущую политику, выполните:
PS > Get-ExecutionPolicy
Скорее всего, он вернёт значение Restricted, что означает, что все скрипты заблокированы. Чтобы разрешить запуск скрипта вашего профиля, откройте PowerShell от имени администратора и установите:
PS > Set-ExecutionPolicy Unrestricted
После подтверждения скрипты будут работать в обычном режиме, включая ваш файл профиля.
PS > Set-Location Windows
Это перенесёт вас в папку Windows в текущем каталоге. PowerShell даже позволяет перемещаться по реестру таким же образом:
PS > Set-Location -Path "HKLM:"
PS > Set-Location -Path "HKEY_LOCAL_MACHINE\SYSTEM\Software\Microsoft\CTF"
PS > Get-ChildItem C:\
Здесь отображаются все данные на диске C:. Чтобы отсортировать результаты по времени изменения (как ls -ltrв Linux):
PS > Get-ChildItem $env:USERPROFILE\Documents | Sort-Object -Property LastWriteTime
Для рекурсивного поиска:
PS > Get-ChildItem -Path C:\ -Force -Recurse
PS > New-Item -ItemType Directory -Name intel
Или чтобы создать подпапку:
PS > New-Item -ItemType "directory" -Path "c:\intel\papers"
Вы даже можете создать текстовый файл с содержимым одной командой:
PS > New-Item -Path . -Name "key.txt" -ItemType "file" -Value "HSDAF8KL"
PS > New-Item -ItemType "file" -Path "c:\temp\file.txt", "C:\intel\papers\classified.txt"
Это создает два файла в разных папках.
PS > Copy-Item -Path C:\intel\classified.txt -Destination C:\important\
Работает также по сети:
PS > Copy-Item -Path C:\key.txt -Destination '\\file-srv\f$\key.txt'
PS > Remove-Item -Recurse -Force
Как и в Linux, это одна из самых опасных команд. Одна ошибка может привести к удалению целых каталогов. Рекомендуется сначала просмотреть, что будет удалено с помощью Get-ChildItem , или даже переименовать файлы вместо их удаления, чтобы упростить восстановление.
Также можно удалять по маскам:
PS > Remove-Item *.txt
Или конкретные файлы:
PS > Remove-Item C:\dir1\records, C:\dir1\photos, C:\dir2\interrogations
PS > Get-ChildItem C:\ -Include *.exe -Recurse
Эта команда нашла все .exe- файлы на C:\, но вы также можете ограничить глубину:
PS > Get-ChildItem -Path "C:\Files\*.exe" -Filter "*software*" -Depth 2 -Exclude "*server*" -Recurse
Обратите внимание, насколько гибкая фильтрация. Часто регулярные выражения не нужны.
PS > Get-Content -Path C:\case\script.txt
PS > Get-Content c:\logs\log.txt -TotalCount 10
Для мониторинга в реальном времени:
PS > Get-Content "C:\logs\log.txt" -Wait | Where { $_ -Match "Error" }
Здесь отображаются новые строки, содержащие слово «Error» по мере их появления.
Список процессов, использующих более 100 МБ памяти:
PS > Get-Process | Where-Object { $_.WorkingSet -gt 104857600 }
Для текстового поиска используйте Select-String, чтобы найти строку, в которой упоминается ваше ключевое слово:
PS > Select-String -Path C:\logs\*.log -Pattern "error"
Или объединить с Get-Content :
PS > Get-Content -Path C:\scripts\script.txt | Select-String -Pattern "alias"
PS > $Properties = 'Caption', 'CSName', 'Version', 'BuildType', 'OSArchitecture'; Get-CimInstance Win32_OperatingSystem | Select-Object $Properties | Format-Table -AutoSize
Длиннее, чем uname -a , но при необходимости можно использовать псевдоним. В конце концов, вы нечасто будете им пользоваться.
PS > New-Volume -StoragePoolName "CompanyData" -FriendlyName "TestVolume" -Size 10GB -ResiliencySettingName "Mirror" -FileSystem NTFS -AccessPath "M:" -ProvisioningType Fixed
Будьте осторожны: неправильное использование может привести к потере ваших данных. Всегда сначала проверяйте на безопасном устройстве.
PS > Test-Connection google.com
PS > Get-ChildItem $env:USERPROFILE -Filter "*.txt" | Select-Object -Property 'Name', 'Length'
PS > Get-Help Get-ChildItem
Вы также можете использовать подстановочные знаки:
PS > Get-Help Get-*
Переход не проходит безболезненно. Синтаксис может показаться громоздким, а шаблоны — непривычными. Кажется, что приходится печатать больше текста для достижения того же результата. В конечном счёте, всё сводится к привычке и практике. PowerShell — это, по сути, полноценный набор инструментов, а Bash — удобный карманный нож. Чем больше вы экспериментируете и анализируете, тем естественнее он будет ощущаться.
При переходе с Bash на PowerShell люди часто сталкиваются с трудностями просто потому, что не знают, какие инструменты PowerShell служат эквивалентами и как ими пользоваться. Например, мне лично Bash нравится своей простой логикой. Если вам нужно извлечь только определённые строки из текстового файла, вы знаете, что можно вызвать cat и grep. Но когда вы пытаетесь ввести что-то подобное в PowerShell, часто возникает ощущение, будто вы упираетесь в стену. Вы знаете логику, вы знаете, что это должно быть всего одна строка, но всё равно не понимаете, как это сделать. Именно это мы и собираемся сегодня разобрать.
Эта статья дополняет книгу «Powershell for Hackers: Basics» и призвана продемонстрировать больше возможностей PowerShell, сопоставляя знакомые команды Bash с их эквивалентами в PowerShell. Если вы ещё не читали «Powershell for Hackers: Basics» , настоятельно рекомендуем начать с неё. Это руководство предназначено для тех, кто знаком с командной строкой Linux и хочет получить практические примеры для своих рабочих процессов в PowerShell.
Общие правила игры
Начнём с самого простого, но при этом очень важного: работы с переменными. В Bash объявление переменной выполняется так же просто, как foo=1 . В PowerShell нужно добавить знак доллара: $foo=1 . Чтобы вывести значение переменной на экран, можно использовать универсальную команду echo или специальный командлет PowerShell Write-Host . Длиннее? Безусловно. Но преимущество Write-Host в том, что вы можете управлять выводом интересными способами:PS > Write-Host (2,4,6,8,10,12) -Separator "->" -ForegroundColor DarkMagenta -BackgroundColor White
Этот фрагмент кода выведет последовательность чисел в скобках, добавит между ними символ -> , а также изменит цвет текста и фона. Для быстрого скрипта это необязательно, но для ежедневного отчёта может быть весьма полезно.
Если вам нужно что-то сравнить, в PowerShell есть полный набор операторов, знакомый любому, кто работал с Linux.
Если операторы сравнения и логические условия более-менее понятны, давайте рассмотрим очень простой, но практичный пример с типами данных. Предположим, мы хотим измерить среднее время ответа веб-сайта, например, google.com . Для этого нам нужно отправить несколько пингов и вычислить среднее значение. Вот короткий скрипт:
Write-Host `n "Waiting for test ..."<br>$Avg = 0<br>$Site = "www.google.com"<br>$PingSite = Test-Connection -Count 5 $Site<br>$Avg = ($PingSite | Measure-Object ResponseTime -Average)<br>$Calc = ($Avg.Average) -as [int]<br>Clear-Host<br>Write-Host "Average response time to $Site is $Calc ms"
Если не преобразовать значение в целое число, мы получим число с плавающей запятой, что не очень удобно для данной цели.
Это один из случаев, когда команда PowerShell на самом деле эффективнее классического ping в Linux. Командлет Test-Connection выводит структурированные объекты, которые уже содержат время ответа, статус и другие полезные свойства. Это означает, что вы можете передавать результаты непосредственно в инструменты, такие как Measure-Object , и выполнять с ними математические операции, не разбирая текст с помощью awk или grep. В Linux ping работает с текстом, поэтому для извлечения чисел часто требуются дополнительные команды. PowerShell пропускает этот шаг.
Псевдонимы
Чтобы упростить использование PowerShell, вы можете создать псевдонимы. Стоит проверить псевдонимы, уже доступные в вашей системе, с помощью:PS > Get-Alias
Псевдонимы могут даже указывать на программы. Например, создадим псевдоним для запуска калькулятора:
PS > Set-Alias -Name calc -Value calc.exe
Теперь ввод команды calc запустит калькулятор. Если вы хотите, чтобы ваш псевдоним представлял команду с параметрами, вам нужно обернуть его в функцию:
function AL01 { Test-Connection -Count 2 google.com }<br>Set-Alias ping AL01
Теперь при вводе команды ping будут выполнены два пинга на google.com . Чтобы удалить псевдоним, используйте:
PS > Remove-Item alias
Обратите внимание: после закрытия PowerShell все созданные вами таким образом псевдонимы исчезнут. Чтобы сохранить их навсегда, необходимо сохранить их в своём профиле. В PowerShell существует четыре возможных профиля. Вы можете просмотреть их с помощью:
PS > $profile | Format-List -Force
Чтобы проверить, существуют ли они в вашей системе:
PS > $profile | Format-List -Force | ForEach-Object { Test-Path $_ }
Если результат — False, файл просто не существует. Вы можете создать его, например, по этому пути:
PS > notepad.exe C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1
И добавьте внутрь него свои псевдонимы:
function AL01 { Test-Connection -Count 2 google.com }<br>Set-Alias ping AL01
После сохранения и перезапуска PowerShell ваши псевдонимы загрузятся автоматически.
Важное замечание. По умолчанию Windows блокирует выполнение внешних скриптов. Это означает, что ваш файл профиля может быть проигнорирован. Чтобы проверить текущую политику, выполните:
PS > Get-ExecutionPolicy
Скорее всего, он вернёт значение Restricted, что означает, что все скрипты заблокированы. Чтобы разрешить запуск скрипта вашего профиля, откройте PowerShell от имени администратора и установите:
PS > Set-ExecutionPolicy Unrestricted
После подтверждения скрипты будут работать в обычном режиме, включая ваш файл профиля.
Идем глубже
Теперь перейдем к наиболее популярным инструментам Linux и их эквивалентам PowerShell, от простых к более продвинутым.компакт-диск
Для навигации между каталогами можно использовать привычный псевдоним cd или командлет Set-Location :PS > Set-Location Windows
Это перенесёт вас в папку Windows в текущем каталоге. PowerShell даже позволяет перемещаться по реестру таким же образом:
PS > Set-Location -Path "HKLM:"
PS > Set-Location -Path "HKEY_LOCAL_MACHINE\SYSTEM\Software\Microsoft\CTF"
лс
Чтобы просмотреть содержимое каталога, используйте ls , dir или командлет Get-ChildItem :PS > Get-ChildItem C:\
Здесь отображаются все данные на диске C:. Чтобы отсортировать результаты по времени изменения (как ls -ltrв Linux):
PS > Get-ChildItem $env:USERPROFILE\Documents | Sort-Object -Property LastWriteTime
Для рекурсивного поиска:
PS > Get-ChildItem -Path C:\ -Force -Recurse
mkdir
Для создания каталогов используйте New-Item :PS > New-Item -ItemType Directory -Name intel
Или чтобы создать подпапку:
PS > New-Item -ItemType "directory" -Path "c:\intel\papers"
Вы даже можете создать текстовый файл с содержимым одной командой:
PS > New-Item -Path . -Name "key.txt" -ItemType "file" -Value "HSDAF8KL"
трогать
Создание файлов также использует New-Item :PS > New-Item -ItemType "file" -Path "c:\temp\file.txt", "C:\intel\papers\classified.txt"
Это создает два файла в разных папках.
ср
Копирование файлов выполняется с помощью Copy-Item :PS > Copy-Item -Path C:\intel\classified.txt -Destination C:\important\
Работает также по сети:
PS > Copy-Item -Path C:\key.txt -Destination '\\file-srv\f$\key.txt'
рм
Удаление файлов — Remove-Item . Опасный эквивалент rm -rf :PS > Remove-Item -Recurse -Force
Как и в Linux, это одна из самых опасных команд. Одна ошибка может привести к удалению целых каталогов. Рекомендуется сначала просмотреть, что будет удалено с помощью Get-ChildItem , или даже переименовать файлы вместо их удаления, чтобы упростить восстановление.
Также можно удалять по маскам:
PS > Remove-Item *.txt
Или конкретные файлы:
PS > Remove-Item C:\dir1\records, C:\dir1\photos, C:\dir2\interrogations
находить
Для поиска файлов используйте Get-ChildItem с фильтрами. Например:PS > Get-ChildItem C:\ -Include *.exe -Recurse
Эта команда нашла все .exe- файлы на C:\, но вы также можете ограничить глубину:
PS > Get-ChildItem -Path "C:\Files\*.exe" -Filter "*software*" -Depth 2 -Exclude "*server*" -Recurse
Обратите внимание, насколько гибкая фильтрация. Часто регулярные выражения не нужны.
кот
Для чтения файлов используйте Get-Content или gc :PS > Get-Content -Path C:\case\script.txt
хвост
Чтобы просмотреть последние десять строк файла:PS > Get-Content c:\logs\log.txt -TotalCount 10
Для мониторинга в реальном времени:
PS > Get-Content "C:\logs\log.txt" -Wait | Where { $_ -Match "Error" }
Здесь отображаются новые строки, содержащие слово «Error» по мере их появления.
grep
В PowerShell нет идеального аналога grep , но есть альтернативы. Для фильтрации объектов используйте Where-Object .Список процессов, использующих более 100 МБ памяти:
PS > Get-Process | Where-Object { $_.WorkingSet -gt 104857600 }
Для текстового поиска используйте Select-String, чтобы найти строку, в которой упоминается ваше ключевое слово:
PS > Select-String -Path C:\logs\*.log -Pattern "error"
Или объединить с Get-Content :
PS > Get-Content -Path C:\scripts\script.txt | Select-String -Pattern "alias"
uname
Для отображения информации о системе:PS > $Properties = 'Caption', 'CSName', 'Version', 'BuildType', 'OSArchitecture'; Get-CimInstance Win32_OperatingSystem | Select-Object $Properties | Format-Table -AutoSize
Длиннее, чем uname -a , но при необходимости можно использовать псевдоним. В конце концов, вы нечасто будете им пользоваться.
МКФС
Для создания файловых систем в PowerShell есть New-Volume и Format-Volume :PS > New-Volume -StoragePoolName "CompanyData" -FriendlyName "TestVolume" -Size 10GB -ResiliencySettingName "Mirror" -FileSystem NTFS -AccessPath "M:" -ProvisioningType Fixed
Будьте осторожны: неправильное использование может привести к потере ваших данных. Всегда сначала проверяйте на безопасном устройстве.
пинг
Классический эквивалент ping — Test-Connection :PS > Test-Connection google.com
резать
Чтобы извлечь только определённые поля, используйте Select-Object . Например, чтобы вывести список текстовых файлов в папке пользователя, но показать только имена и размеры:PS > Get-ChildItem $env:USERPROFILE -Filter "*.txt" | Select-Object -Property 'Name', 'Length'
мужчина
Эквивалент man — Get -Help :PS > Get-Help Get-ChildItem
Вы также можете использовать подстановочные знаки:
PS > Get-Help Get-*
Заключение
Как видите, почти у каждой команды Linux есть достойный аналог в PowerShell. Некоторые из них менее элегантны или более многословны, но зато часто дают больше возможностей благодаря структурированным объектам и расширенной фильтрации. Bash и PowerShell подходят к одним и тем же задачам с разных сторон. Bash — это язык коротких, чётких однострочных команд, язык быстрых хаков и объединения небольших инструментов. PowerShell требует больше слов для начала работы, но это окупается глубиной. Его командлеты работают с объектами, а не с обычным текстом, что обеспечивает большую точность и гибкость. Задачу, для которой в Bash требуется три-четыре утилиты, объединённые вместе, иногда можно решить одним командлетом.Переход не проходит безболезненно. Синтаксис может показаться громоздким, а шаблоны — непривычными. Кажется, что приходится печатать больше текста для достижения того же результата. В конечном счёте, всё сводится к привычке и практике. PowerShell — это, по сути, полноценный набор инструментов, а Bash — удобный карманный нож. Чем больше вы экспериментируете и анализируете, тем естественнее он будет ощущаться.