PowerShell. Примеры использования
Windows PowerShell — это одновременно командная оболочка и язык сценариев, основанный на .NET. PowerShell используют для управления компьютером и автоматизации задач. Это полноценный объектно-ориентированный язык, в котором есть переменные, циклы, условия, функции, классы и объекты.
В отличие от других командных оболочек, PowerShell работает не со строками, а с объектами. Благодаря этому можно создавать сложную логику. При этом интерпретатор полностью совместим со стандартными командами cmd.exe и может выполнять их.
Примеры использования
Первый пример
Скрипт демонстрирует основные возможности языка — переменные, функции, условия, циклы.
# ============================================ # Пример скрипта PowerShell # Демонстрирует основные возможности языка # ============================================ # --- Переменные --- $name = "Алексей" $age = 30 # --- Вывод текста --- Write-Host "Привет, $name! Тебе $age лет." # --- Условие --- if ($age -ge 18) { Write-Host "Ты совершеннолетний." } else { Write-Host "Ты несовершеннолетний." } # --- Массив и цикл --- $fruits = @("Яблоко", "Банан", "Вишня") foreach ($fruit in $fruits) { Write-Host "Фрукт: $fruit" } # --- Функция --- function Get-Square { param ( [int]$number # параметр функции ) return $number * $number } $result = Get-Square -number 7 Write-Host "Квадрат числа 7 = $result" # --- Работа с файлами --- $filePath = "C:\Temp\test.txt" # Записываем текст в файл "Привет из PowerShell!" | Out-File -FilePath $filePath -Encoding UTF8 # Читаем файл обратно $content = Get-Content -Path $filePath Write-Host "Содержимое файла: $content" # --- Обработка ошибок --- try { $x = 10 / 0 # деление на ноль вызовет ошибку } catch { Write-Host "Ошибка: $_" # $_ содержит текст исключения } finally { Write-Host "Блок finally выполняется всегда." }
Что здесь показано
| Возможность | Пример в коде |
|---|---|
| Переменные | $name, $age |
| Условия | if / else |
| Циклы | foreach |
| Функции | function Get-Square |
| Работа с файлами | Out-File, Get-Content |
| Обработка ошибок | try / catch / finally |
Несколько нюансов
- Переменные всегда начинаются с символа
$ - Сравнения пишутся как
-eq,-ne,-gt,-ge - Командлеты имеют форму
Глагол-Существительное
Второй пример
Скрипт собирает базовую информацию о компьютере и сохраняет её в текстовый файл.
# ============================================ # Скрипт: Отчёт о состоянии системы # Сохраняет информацию о ПК в текстовый файл # ============================================ # Путь к файлу отчёта (на рабочем столе текущего пользователя) $reportPath = "$env:USERPROFILE\Desktop\report.txt" # Функция: добавляет строку в отчёт и одновременно выводит в консоль function Write-Report { param([string]$line) $line | Out-File -FilePath $reportPath -Append -Encoding UTF8 Write-Host $line } # Очищаем старый файл, если существует if (Test-Path $reportPath) { Remove-Item $reportPath } # --- Дата и время --- Write-Report "=== Отчёт от $(Get-Date -Format 'dd.MM.yyyy HH:mm') ===" Write-Report "" # --- Имя компьютера и пользователя --- Write-Report "Компьютер : $env:COMPUTERNAME" Write-Report "Пользователь: $env:USERNAME" Write-Report "" # --- Версия Windows --- $os = Get-CimInstance Win32_OperatingSystem Write-Report "ОС : $($os.Caption)" Write-Report "Версия : $($os.Version)" Write-Report "" # --- Оперативная память --- $totalRam = [math]::Round($os.TotalVisibleMemorySize / 1MB, 1) # в ГБ $freeRam = [math]::Round($os.FreePhysicalMemory / 1MB, 1) $usedRam = [math]::Round($totalRam - $freeRam, 1) Write-Report "--- Оперативная память ---" Write-Report "Всего : $totalRam ГБ" Write-Report "Занято: $usedRam ГБ" Write-Report "Свободно: $freeRam ГБ" Write-Report "" # --- Диски --- Write-Report "--- Диски ---" $disks = Get-PSDrive -PSProvider FileSystem # получаем все файловые диски foreach ($disk in $disks) { # Пропускаем диски без информации об объёме (сетевые папки и т.п.) if ($disk.Used -eq $null -or $disk.Free -eq $null) { continue } $used = [math]::Round($disk.Used / 1GB, 1) $free = [math]::Round($disk.Free / 1GB, 1) $total = [math]::Round($used + $free, 1) Write-Report "Диск $($disk.Name): $used ГБ занято / $total ГБ всего (свободно: $free ГБ)" } Write-Report "" Write-Report "=== Отчёт сохранён: $reportPath ==="
Пример вывода
=== Отчёт от 05.05.2026 14:22 === Компьютер : DESKTOP-AB12 Пользователь: alex ОС : Microsoft Windows 11 Pro Версия : 10.0.22631 --- Оперативная память --- Всего : 15.9 ГБ Занято : 9.2 ГБ Свободно : 6.7 ГБ --- Диски --- Диск C: 112.4 ГБ занято / 476.9 ГБ всего (свободно: 364.5 ГБ) Диск D: 540.1 ГБ занято / 931.5 ГБ всего (свободно: 391.4 ГБ)
Что полезного в этом скрипте
$env:USERPROFILE— обращение к переменным окружения WindowsGet-CimInstance— получение данных об оборудовании через WMIGet-PSDrive— информация о дисках[math]::Round()— вызов методов.NETпрямо из PowerShell
Третий пример
Скрипт берёт все файлы из указанной папки и раскладывает их по подпапкам согласно расширению.
# ============================================ # Скрипт: Сортировка файлов по расширениям # Например: file.mp3 → Музыка\file.mp3 # ============================================ # Папка, которую будем сортировать (можно изменить) $sourceFolder = "$env:USERPROFILE\Downloads" # Таблица соответствий: расширение → название папки $categories = @{ ".jpg" = "Изображения" ".jpeg" = "Изображения" ".png" = "Изображения" ".gif" = "Изображения" ".mp3" = "Музыка" ".wav" = "Музыка" ".flac" = "Музыка" ".mp4" = "Видео" ".avi" = "Видео" ".mkv" = "Видео" ".pdf" = "Документы" ".docx" = "Документы" ".xlsx" = "Документы" ".txt" = "Документы" ".zip" = "Архивы" ".rar" = "Архивы" ".7z" = "Архивы" } # Счётчики для итогового отчёта $moved = 0 $skipped = 0 # Получаем все файлы в папке (без вложенных папок) $files = Get-ChildItem -Path $sourceFolder -File foreach ($file in $files) { $ext = $file.Extension.ToLower() # расширение в нижнем регистре # Ищем расширение в таблице if ($categories.ContainsKey($ext)) { $targetFolder = Join-Path $sourceFolder $categories[$ext] # Создаём папку, если её ещё нет if (-not (Test-Path $targetFolder)) { New-Item -ItemType Directory -Path $targetFolder | Out-Null Write-Host "Создана папка: $($categories[$ext])" } # Перемещаем файл Move-Item -Path $file.FullName -Destination $targetFolder Write-Host "Перемещён: $($file.Name) → $($categories[$ext])" $moved++ } else { # Расширение не найдено в таблице — пропускаем Write-Host "Пропущен : $($file.Name) (расширение '$ext' не задано)" $skipped++ } } # Итоговая сводка Write-Host "" Write-Host "=== Готово ===" Write-Host "Перемещено : $moved файлов" Write-Host "Пропущено : $skipped файлов"
Пример вывода
Создана папка: Изображения Перемещён: photo.jpg → Изображения Перемещён: wallpaper.png → Изображения Создана папка: Музыка Перемещён: song.mp3 → Музыка Пропущен : setup.exe (расширение '.exe' не задано) === Готово === Перемещено : 3 файлов Пропущено : 1 файлов
Что нового в этом примере
| Что нового | Что делает |
|---|---|
@{ } — хэш-таблица |
словарь «ключ → значение» |
ContainsKey() |
проверка наличия ключа в таблице |
Join-Path |
правильно склеивает пути (сам ставит \) |
New-Item |
создание файла или папки |
Move-Item |
перемещение файла |
Get-ChildItem -File |
список только файлов, без папок |
Самые популярные командлеты
Работа с файлами и папками
# Список файлов в папке Get-ChildItem -Path "C:\Temp" Get-ChildItem -Path "C:\Temp" -Filter "*.txt" # только .txt файлы Get-ChildItem -Path "C:\Temp" -Recurse # включая вложенные папки # Копировать, переместить, удалить Copy-Item -Path "C:\file.txt" -Destination "D:\file.txt" Move-Item -Path "C:\file.txt" -Destination "D:\file.txt" Remove-Item -Path "C:\file.txt" Remove-Item -Path "C:\folder" -Recurse # удалить папку со всем содержимым # Создать файл или папку New-Item -ItemType File -Path "C:\Temp\log.txt" New-Item -ItemType Directory -Path "C:\Temp\NewFolder" # Проверить существование Test-Path "C:\Temp\file.txt" # вернёт True или False
Чтение и запись файлов
# Читать файл (возвращает массив строк) $lines = Get-Content "C:\log.txt" $lines = Get-Content "C:\log.txt" -Tail 10 # последние 10 строк # Записать в файл "Hello World" | Out-File "C:\log.txt" # перезаписать "Новая строка" | Out-File "C:\log.txt" -Append # добавить в конец Set-Content -Path "C:\log.txt" -Value "текст" # перезаписать Add-Content -Path "C:\log.txt" -Value "ещё строка" # добавить
Фильтрация и сортировка
# Where-Object — фильтрует (аналог WHERE в SQL) Get-ChildItem "C:\Temp" | Where-Object { $_.Extension -eq ".txt" } Get-ChildItem "C:\Temp" | Where-Object { $_.Length -gt 1MB } # файлы > 1 МБ # Select-Object — выбирает нужные свойства Get-ChildItem "C:\Temp" | Select-Object Name, Length, LastWriteTime # Sort-Object — сортировка Get-ChildItem "C:\Temp" | Sort-Object Length -Descending # по размеру, убыванию # Measure-Object — подсчёт, сумма, среднее Get-ChildItem "C:\Temp" | Measure-Object Length -Sum # суммарный размер Get-ChildItem "C:\Temp" | Measure-Object # просто количество
Работа со строками
$s = " Привет, Мир! " $s.ToLower() # → " привет, мир! " $s.ToUpper() # → " ПРИВЕТ, МИР! " $s.Trim() # → "Привет, Мир!" убрать пробелы по краям $s.Replace("Мир", "PowerShell") # → " Привет, PowerShell! " $s.Contains("Привет") # → True $s.Split(",") # → [" Привет", " Мир! "] $s.Length # → 16
Процессы и система
# Список запущенных процессов Get-Process Get-Process -Name "chrome" # найти конкретный процесс # Остановить процесс Stop-Process -Name "notepad" Stop-Process -Id 1234 # по ID # Сервисы Windows Get-Service Get-Service -Name "wuauserv" # служба обновлений Windows Start-Service -Name "wuauserv" Stop-Service -Name "wuauserv" Restart-Service -Name "wuauserv" # Информация о системе Get-ComputerInfo # всё о компьютере Get-Date # текущая дата и время
Работа с сетью
# Проверить доступность хоста (аналог ping) Test-Connection google.com Test-Connection google.com -Count 2 # 2 пинга # Скачать файл из интернета Invoke-WebRequest -Uri "https://example.com/file.zip" -OutFile "C:\file.zip" # Получить содержимое веб-страницы или API $response = Invoke-RestMethod -Uri "https://api.example.com/data"
Форматирование вывода
Get-Process | Format-Table Name, CPU, WorkingSet # вывод таблицей Get-Process | Format-List # вывод списком (подробно) Get-Process | Out-GridView # открыть в графическом окне! Get-Process | Export-Csv "C:\processes.csv" # сохранить в CSV Get-Process | ConvertTo-Json # преобразовать в JSON
В PowerShell командлеты строятся по схеме Глагол-Существительное, и глаголы повторяются.
| Глагол | Смысл |
|---|---|
Get- |
получить / прочитать |
Set- |
изменить / установить |
New- |
создать |
Remove- |
удалить |
Start- |
запустить |
Stop- |
остановить |
Copy- |
скопировать |
Move- |
переместить |
Test- |
проверить (вернёт True/False) |
Export- |
экспортировать |
Convert- |
преобразовать |
Invoke- |
выполнить / вызвать |
Зная эту логику, название нужного командлета часто можно угадать не глядя в документацию.
Параметры скрипта
Базовый пример — файл greet.ps1
# Блок param() всегда объявляется в самом начале скрипта param ( [string]$name, # имя пользователя [int]$age # возраст ) Write-Host "Привет, $name! Тебе $age лет."
Запуск скрипта из консоли
.\greet.ps1 -name "Алексей" -age 30 # → Привет, Алексей! Тебе 30 лет.
Если параметр помечен как обязательный, PowerShell сам спросит его значение, если не передали.
param ( [Parameter(Mandatory)] [string]$name, [Parameter(Mandatory)] [int]$age ) Write-Host "Привет, $name! Тебе $age лет."
# Запуск без параметров .\greet.ps1 # PowerShell сам остановится и спросит: # Введите значение для следующих параметров: # name: Алексей # age: 30
Значения по умолчанию для параметров
param ( [string]$name = "Гость", # если не передали — будет "Гость" [int]$age = 0 ) Write-Host "Привет, $name! Тебе $age лет."
.\greet.ps1 -name "Алексей" # age не передали # → Привет, Алексей! Тебе 0 лет. .\greet.ps1 # ничего не передали # → Привет, Гость! Тебе 0 лет.
Иногда нужно проверить параметры самостоятельно и вывести понятное сообщение об ошибке.
param ( [string]$sourceFolder, [string]$targetFolder, [int]$minSize = 0 ) # --- Проверяем обязательные параметры --- if (-not $sourceFolder) { Write-Host "Ошибка: не указана исходная папка (-sourceFolder)" -ForegroundColor Red Write-Host "Пример: .\script.ps1 -sourceFolder C:\Temp -targetFolder D:\Backup" exit 1 # завершаем скрипт с кодом ошибки } if (-not $targetFolder) { Write-Host "Ошибка: не указана папка назначения (-targetFolder)" -ForegroundColor Red Write-Host "Пример: .\script.ps1 -sourceFolder C:\Temp -targetFolder D:\Backup" exit 1 } # --- Проверяем существование папки --- if (-not Test-Path $sourceFolder) { Write-Host "Ошибка: папка '$sourceFolder' не существует" -ForegroundColor Red exit 1 } # --- Проверяем корректность числового параметра --- if ($minSize -lt 0) { Write-Host "Ошибка: minSize не может быть отрицательным" -ForegroundColor Red exit 1 } # Если дошли сюда — всё в порядке Write-Host "Копируем файлы из '$sourceFolder' в '$targetFolder'..." Write-Host "Минимальный размер файла: $minSize байт"
Запуск скрипта
# Без параметров .\script.ps1 # → Ошибка: не указана исходная папка (-sourceFolder) # → Пример: .\script.ps1 -sourceFolder C:\Temp -targetFolder D:\Backup # Правильный запуск .\script.ps1 -sourceFolder "C:\Temp" -targetFolder "D:\Backup" -minSize 1024 # → Копируем файлы из 'C:\Temp' в 'D:\Backup'... # → Минимальный размер файла: 1024 байт
PowerShell позволяет добавить описание прямо в код, тогда Get-Help покажет его.
<# .SYNOPSIS Копирует файлы из одной папки в другую. .PARAMETER sourceFolder Исходная папка с файлами. .PARAMETER targetFolder Папка назначения. .PARAMETER minSize Минимальный размер файла в байтах. По умолчанию 0. .EXAMPLE .\script.ps1 -sourceFolder "C:\Temp" -targetFolder "D:\Backup" .EXAMPLE .\script.ps1 -sourceFolder "C:\Temp" -targetFolder "D:\Backup" -minSize 1024 #> param ( [string]$sourceFolder, [string]$targetFolder, [int]$minSize = 0 )
# Теперь можно вызвать справку Get-Help .\script.ps1 # Или с примерами Get-Help .\script.ps1 -Examples
Итого — способы обработки отсутствующих параметров
| Способ | Когда использовать |
|---|---|
[Parameter(Mandatory)] |
PowerShell сам спрашивает значение — удобно для интерактивных скриптов |
Значение по умолчанию = "value" |
Когда параметр необязателен и есть разумное значение |
Ручная проверка if (-not $param) |
Когда нужно вывести подробное сообщение об ошибке |
exit 1 |
Завершить скрипт с кодом ошибки (используется в автоматизации) |
Специальные переменные
Чаще всего используется $_ — специальная автоматическая переменная, которую PowerShell создаёт сам. Она означает «текущий объект» и используется внутри блоков кода { }.
Когда объекты передаются по конвейеру, $_ — это тот объект, который обрабатывается прямо сейчас.
1, 2, 3, 4, 5 | ForEach-Object { $_ * 2 } # → 2, 4, 6, 8, 10 Get-ChildItem "C:\Temp" | Where-Object { $_.Extension -eq ".txt" } # ^^ # текущий файл из списка
"яблоко", "банан", "вишня" | ForEach-Object { Write-Host "Фрукт: $($_.ToUpper())" } # → Фрукт: ЯБЛОКО # → Фрукт: БАНАН # → Фрукт: ВИШНЯ
Еще одно место, где можно встретить $_ — это блок catch, где эта переменная будет содержать текст исключения.
try { 1 / 0 } catch { Write-Host "Ошибка: $_" # $_ содержит текст исключения }
Переменная $_ в конвейере — это то же самое, что переменная в обычном foreach, просто без явного объявления.
# Эти два варианта делают одно и то же: # Вариант 1 — foreach (переменная объявлена явно) foreach ($file in Get-ChildItem "C:\Temp") { Write-Host $file.Name } # Вариант 2 — конвейер (используется $_) Get-ChildItem "C:\Temp" | ForEach-Object { Write-Host $_.Name }
Другие специальные переменные
| Переменная | Что содержит |
|---|---|
$_ |
текущий объект в конвейере |
$? |
результат последней команды (True/False) |
$null |
пустое значение (аналог null) |
$true / $false |
булевы константы |
$env:USERNAME |
переменные окружения Windows |
$PSVersionTable |
версия PowerShell |
$args |
аргументы, переданные скрипту |
$Error |
список последних ошибок |
# Примеры Write-Host $PSVersionTable.PSVersion # → 7.4.0 Write-Host $null -eq $null # → True Write-Host $true # → True
Массивы и хэш-таблицы
Массивы
Создание массива
# Обычный массив $fruits = @("яблоко", "банан", "вишня") # Можно без @() — PowerShell поймёт сам $fruits = "яблоко", "банан", "вишня" # Массив чисел $numbers = @(1, 2, 3, 4, 5) # Пустой массив $empty = @() # Массив из диапазона чисел $range = 1..10 # → 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 # Массив разных типов $mixed = @("текст", 42, $true, 3.14)
Обращение к элементам
$fruits = @("яблоко", "банан", "вишня", "груша") $fruits[0] # → яблоко (первый элемент) $fruits[1] # → банан $fruits[-1] # → груша (последний элемент) $fruits[-2] # → вишня (предпоследний) # Срез — несколько элементов сразу $fruits[0..2] # → яблоко, банан, вишня $fruits[0, 2] # → яблоко, вишня (только 0 и 2 индекс)
Основные операции
$fruits = @("яблоко", "банан", "вишня") # Количество элементов $fruits.Count # → 3 $fruits.Length # → 3 (то же самое) # Добавить элемент (создаёт новый массив) $fruits += "груша" $fruits # → яблоко, банан, вишня, груша # Проверить наличие элемента $fruits -contains "банан" # → True $fruits -contains "манго" # → False # Найти индекс элемента $fruits.IndexOf("вишня") # → 2 # Сортировка $fruits | Sort-Object # по алфавиту $fruits | Sort-Object -Descending # Отфильтровать $fruits | Where-Object { $_.Length -gt 5 } # слова длиннее 5 букв # → яблоко, банан # Перебор элементов foreach ($fruit in $fruits) { Write-Host $fruit } # То же самое через конвейер $fruits | ForEach-Object { Write-Host $_ }
Полезные методы
$numbers = @(3, 1, 4, 1, 5, 9, 2, 6) # Сортировка $numbers | Sort-Object # → 1, 1, 2, 3, 4, 5, 6, 9 # Уникальные значения $numbers | Sort-Object -Unique # → 1, 2, 3, 4, 5, 6, 9 # Статистика $numbers | Measure-Object -Sum -Average -Maximum -Minimum # Sum : 31 # Average : 3.875 # Maximum : 9 # Minimum : 1 # Соединить в строку $fruits = @("яблоко", "банан", "вишня") $fruits -join ", " # → "яблоко, банан, вишня" $fruits -join " | " # → "яблоко | банан | вишня" # Разбить строку в массив "яблоко, банан, вишня" -split ", " # → @("яблоко", "банан", "вишня")
Хэш-таблицы
Создание хэш-таблицы
# Обычная хэш-таблица (ключ = значение) $person = @{ Name = "Алексей" Age = 30 City = "Москва" } # Пустая хэш-таблица $empty = @{}
Обращение к элементам
$person = @{ Name = "Алексей" Age = 30 City = "Москва" } # Два равнозначных способа получить значение $person["Name"] # → Алексей $person.Name # → Алексей (удобнее) # Получить все ключи $person.Keys # → Name, Age, City # Получить все значения $person.Values # → Алексей, 30, Москва
Основные операции
$person = @{ Name = "Алексей"; Age = 30 } # Добавить пару ключ-значение $person.Phone = "+7-999-123-45-67" # Изменить значение ключа $person.Age = 31 # Удалить пару ключ-значение $person.Remove("Phone") # Проверить наличие ключа $person.ContainsKey("Name") # → True $person.ContainsKey("Login") # → False # Проверить наличие значения $person.ContainsValue("Алексей") # → True # Количество элементов $person.Count # → 2 # Перебор всех пар ключ-значение foreach ($key in $person.Keys) { Write-Host "$key : $($person[$key])" } # → Name : Алексей # → Age : 31
Массив хэш-таблиц
Очень популярная комбинация — как таблица с данными
# Список сотрудников $employees = @( @{ Name = "Алексей"; Age = 30; Dept = "Разработка" }, @{ Name = "Мария"; Age = 25; Dept = "Дизайн" }, @{ Name = "Иван"; Age = 35; Dept = "Разработка" }, @{ Name = "Ольга"; Age = 28; Dept = "Дизайн" } ) # Вывести всех foreach ($emp in $employees) { Write-Host "$($emp.Name), $($emp.Age) лет, отдел: $($emp.Dept)" } # Найти только разработчиков $developers = $employees | Where-Object { $_.Dept -eq "Разработка" } $developers | ForEach-Object { Write-Host $_.Name } # → Алексей # → Иван # Отсортировать по возрасту $employees | Sort-Object { $_.Age } | ForEach-Object { Write-Host "$($_.Name) — $($_.Age) лет" } # → Мария — 25 лет # → Ольга — 28 лет # → Алексей — 30 лет # → Иван — 35 лет
Быстрое сравнение
Массив @() |
Хэш-таблица @{} |
|
|---|---|---|
| Что хранит | список значений | пары ключ → значение |
| Доступ к элементу | по индексу [0] |
по ключу ["Name"] |
| Порядок элементов | сохраняется | не гарантируется |
| Когда использовать | перечень однотипных данных | объект с именованными полями |
$array = @("а", "б", "в") # доступ: $array[0] $hash = @{ key = "value" } # доступ: $hash["key"] или $hash.key
Поиск: CLI • Windows • PowerShell