LEARN X · ЗА 15 МИН

PowerShell

PowerShell за 15 минут: вывод, переменные, командлеты и конвейер, строки, циклы, объекты, функции, обработка ошибок и работа с файлами.

PowerShell — кросс-платформенная оболочка и язык сценариев от Microsoft, построенный вокруг объектов, а не текста. Команды называются по схеме Verb-Noun (Get-Process, Set-Item), а конвейер передаёт между ними целые объекты .NET. Этот экспресс-тур проведёт по всему языку на одной странице: почти без прозы, всё знание упаковано в комментарии к рабочему коду.

Вывод и комментарии

# Однострочный комментарий начинается с решётки

<#
  Многострочный (блочный) комментарий
  заключается между <# и #>
#>

Write-Output "Привет, мир"   # основной вывод: идёт в конвейер, его можно поймать переменной
"Просто строка"               # выражение само по себе тоже попадает в вывод

Write-Host "Сразу на экран"   # печатает в консоль напрямую, в конвейер НЕ попадает
Write-Host "Красный текст" -ForegroundColor Red   # с цветом

Write-Verbose "Подробности"   # видно только при -Verbose
Write-Warning "Осторожно!"    # жёлтое предупреждение
# Write-Error "Ошибка"        # пишет в поток ошибок

Переменные и типы

Имена переменных начинаются с $. Типы можно не указывать, но можно и зафиксировать в квадратных скобках.

$name = "Аня"          # тип выводится автоматически (string)
$age  = 30             # int
$pi   = 3.14           # double
$ok   = $true          # bool: $true / $false
$nothing = $null       # отсутствие значения

# Явная типизация: значение приводится к указанному типу
[int]$count = "42"     # строка "42" станет числом 42
[string]$s = 123       # число станет строкой "123"
[bool]$flag = 1        # 1 -> $true

$count.GetType().Name  # => Int32  (узнать тип значения)

# Автоматические переменные (создаёт сам PowerShell):
$PSVersionTable.PSVersion  # версия PowerShell
$PWD                       # текущий каталог
$HOME                      # домашний каталог пользователя
$args                      # массив аргументов скрипта
$_                         # текущий объект в конвейере
$?                         # успех последней команды ($true/$false)
$PID                       # идентификатор процесса

Командлеты и конвейер

Командлеты именуются по схеме Глагол-Существительное (Verb-Noun). Конвейер | передаёт объекты от команды к команде.

Get-Date              # получить текущую дату/время
Get-Process           # список процессов (объекты, а не текст!)
Get-Command Get-*     # найти все командлеты-геттеры
Get-Help Get-Process  # справка по командлету

# Конвейер: вывод слева становится входом справа
Get-Process | Sort-Object CPU -Descending | Select-Object -First 3
# берём процессы -> сортируем по CPU -> оставляем 3 верхних

# Распространённые глаголы:
#   Get-   получить        Set-   изменить
#   New-   создать         Remove- удалить
#   Start- запустить       Stop-  остановить

New-Item file.txt -ItemType File   # создать файл
Get-Member -InputObject (Get-Date) # посмотреть свойства/методы объекта

# Псевдонимы (alias) для частых команд:
# ls / dir -> Get-ChildItem,  cat -> Get-Content,  cd -> Set-Location

Строки

$user = "Боб"

# Двойные кавычки -> интерполяция (подстановка переменных)
"Привет, $user"            # => Привет, Боб
"Длина имени: $($user.Length)"  # $(...) — вычислить выражение внутри строки

# Одинарные кавычки -> БЕЗ подстановки, дословно
'Привет, $user'           # => Привет, $user

# Методы строк (это объекты .NET):
"powershell".ToUpper()     # => POWERSHELL
"  обрезать  ".Trim()       # => обрезать
"a,b,c".Split(",")          # => массив a b c
"Hello".Replace("l", "L")   # => HeLLo
"abcdef".Substring(0, 3)    # => abc

# Конкатенация и повтор
"раз" + "два"              # => раздва
"=" * 10                    # => ==========

# Форматирование оператором -f (как {0}, {1})
"{0} стоит {1:C}" -f "Кофе", 250   # подставит значения, :C — формат валюты
"{0:D3}" -f 7                       # => 007 (дополнение нулями)

# Многострочная строка (here-string)
$text = @"
Строка 1
Строка 2 с $user
"@

Операторы и условия

В PowerShell операторы сравнения — это слова с дефисом, а не символы.

# Сравнение:
#   -eq равно        -ne не равно
#   -gt больше       -lt меньше
#   -ge больше/равно -le меньше/равно
5 -gt 3            # => True
"abc" -eq "ABC"     # => True (по умолчанию без учёта регистра)
"abc" -ceq "ABC"    # => False (-c... — с учётом регистра)

# Логические: -and  -or  -not (или !)
($age -ge 18) -and ($ok)     # оба истинны
-not $false                  # => True

# Прочие операторы
5 -in @(1,5,9)               # => True (входит в массив)
"hello" -like "h*"           # => True (подстановка * ?)
"abc123" -match "\d+"        # => True (регулярное выражение)

# if / elseif / else
$n = 7
if ($n -lt 0) {
    "отрицательное"
} elseif ($n -eq 0) {
    "ноль"
} else {
    "положительное"           # => сюда
}

# switch — выбор по значению
switch ($n) {
    1 { "один" }
    7 { "семь"; break }       # => семь
    default { "другое" }
}

Циклы

# for — классический счётчик
for ($i = 0; $i -lt 3; $i++) {
    Write-Output $i           # => 0 1 2
}

# foreach — перебор коллекции (ключевое слово)
foreach ($item in @("a", "b", "c")) {
    Write-Output $item        # => a b c
}

# ForEach-Object — перебор В КОНВЕЙЕРЕ, текущий элемент = $_
1..3 | ForEach-Object { $_ * 10 }   # => 10 20 30
# 1..3 — оператор диапазона, даёт 1,2,3

# while — пока условие истинно
$x = 0
while ($x -lt 3) {
    $x++
}                              # $x станет 3

# do-while — тело выполнится хотя бы раз
do {
    "повтор"
} while ($false)               # выполнится 1 раз

# break — выйти из цикла, continue — к следующей итерации
foreach ($i in 1..5) {
    if ($i -eq 3) { continue } # пропустить 3
    if ($i -eq 5) { break }    # остановиться на 5
    Write-Output $i            # => 1 2 4
}

Массивы и хеш-таблицы

# Массив создаётся через @( ) или просто запятыми
$arr = @(1, 2, 3, 4)
$arr2 = "a", "b", "c"

$arr[0]          # => 1   (доступ по индексу с нуля)
$arr[-1]         # => 4   (последний элемент)
$arr[1..2]       # => 2 3 (срез)
$arr.Count       # => 4   (количество)

$arr += 5        # добавить элемент (создаётся новый массив)
$arr -contains 3 # => True

# Хеш-таблица (словарь) — @{ ключ = значение }
$user = @{
    Name = "Аня"
    Age  = 30
}
$user["Name"]    # => Аня
$user.Age        # => 30   (доступ через точку)
$user.City = "Москва"     # добавить пару
$user.Keys       # все ключи
$user.Remove("Age")       # удалить ключ

# Перебор хеш-таблицы
foreach ($pair in $user.GetEnumerator()) {
    "$($pair.Key) = $($pair.Value)"
}

Объекты и свойства

Конвейер передаёт объекты, поэтому их можно фильтровать, сортировать и выбирать поля.

# Select-Object — выбрать нужные свойства (столбцы)
Get-Process | Select-Object Name, Id, CPU

Get-Process | Select-Object -First 5       # первые 5
Get-Process | Select-Object -Unique Name   # без дублей

# Where-Object — фильтр (строки), условие по $_
Get-Process | Where-Object { $_.CPU -gt 10 }
Get-Process | Where-Object Name -eq "pwsh"  # короткий синтаксис

# Sort-Object — сортировка
Get-Process | Sort-Object CPU -Descending

# Measure-Object — агрегаты (сумма, среднее, максимум)
1..10 | Measure-Object -Sum -Average

# Создать свой объект
$obj = [PSCustomObject]@{
    Имя   = "Книга"
    Цена  = 500
}
$obj.Цена         # => 500

# Вычисляемое свойство в Select-Object
Get-Process | Select-Object Name, @{ Name = "МБ"; Expression = { $_.WS / 1MB } }
# 1MB — числовая константа (1048576)

Функции

# Простая функция
function Get-Square {
    param($x)              # объявление параметров
    return $x * $x         # return необязателен: любой вывод и так возвращается
}
Get-Square 5              # => 25  (аргументы через пробел, БЕЗ скобок!)

# Параметры с типами и значениями по умолчанию
function Greet {
    param(
        [string]$Name = "гость",
        [int]$Times = 1
    )
    for ($i = 0; $i -lt $Times; $i++) {
        "Привет, $Name"
    }
}
Greet -Name "Боб" -Times 2   # вызов по именам параметров
Greet "Аня"                  # => Привет, гость? нет: => Привет, Аня (позиционно)

# Обязательный параметр и приём из конвейера
function Double {
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [int]$Number
    )
    process { $Number * 2 }   # блок process — для каждого элемента конвейера
}
1, 2, 3 | Double             # => 2 4 6

# Функция может вернуть несколько значений (станут массивом)
function Get-Pair { 1; 2 }
$a, $b = Get-Pair            # деструктуризация: $a=1, $b=2

Обработка ошибок

try {
    $result = 1 / 0          # вызовет ошибку
    Get-Item "нет-файла.txt" -ErrorAction Stop  # Stop делает ошибку перехватываемой
}
catch {
    Write-Host "Поймана ошибка: $($_.Exception.Message)"
    # $_ внутри catch — это объект ошибки (ErrorRecord)
}
finally {
    Write-Host "Выполнится в любом случае"   # очистка ресурсов
}

# Ловля конкретного типа исключения
try {
    [int]"не число"
}
catch [System.Management.Automation.RuntimeException] {
    "Ошибка приведения типа"
}

# -ErrorAction управляет реакцией командлета на ошибку:
#   Stop          — прервать (можно поймать в try/catch)
#   Continue      — показать ошибку и продолжить (по умолчанию)
#   SilentlyContinue — молча проигнорировать
Get-Item "нет.txt" -ErrorAction SilentlyContinue

# $Error — массив последних ошибок сессии
$Error[0]          # самая свежая ошибка
$Error.Count       # сколько ошибок накопилось

# Сгенерировать свою ошибку
# throw "Что-то пошло не так"

Работа с файлами и системой

# Чтение файла
Get-Content "data.txt"              # вернёт массив строк
Get-Content "data.txt" -Raw         # одной строкой целиком
Get-Content "log.txt" -Tail 10      # последние 10 строк

# Запись и добавление
Set-Content "out.txt" -Value "Новое содержимое"   # перезаписать
Add-Content "out.txt" -Value "Ещё строка"          # дописать в конец
"Текст" | Out-File "out.txt"        # вывод конвейера в файл

# Просмотр каталога
Get-ChildItem                       # содержимое текущей папки (alias: ls, dir)
Get-ChildItem -Path C:\ -Recurse -Filter "*.log"   # рекурсивный поиск по маске
Get-ChildItem | Where-Object { $_.Length -gt 1MB }  # файлы крупнее 1 МБ

# Проверки и операции
Test-Path "out.txt"                 # => True/False — существует ли путь
New-Item "папка" -ItemType Directory   # создать каталог
Copy-Item "a.txt" "b.txt"           # копировать
Move-Item "b.txt" "архив\"          # переместить
Remove-Item "out.txt"               # удалить

# Системная информация и переменные окружения
$env:PATH                           # переменная окружения PATH
$env:USERNAME                       # имя пользователя
Get-Service | Where-Object Status -eq "Running"   # запущенные службы

# JSON: туда и обратно
$obj | ConvertTo-Json               # объект -> JSON-строка
Get-Content "data.json" -Raw | ConvertFrom-Json   # JSON -> объект
Поддержать проект