REST-запрос в административном скрипте должен иметь понятный результат и предсказуемое поведение при сбое. Успешный одиночный GET ещё не означает, что код готов для задания по расписанию: нужно учитывать кодировку, пагинацию, ограничение частоты, секреты и повторное выполнение операций.
Определить контракт API
До написания клиента выпишите базовый адрес, способ авторизации, необходимые методы, формат ошибок и схему пагинации. Не предполагается, что каждый сервис возвращает items и next: это поля учебного примера ниже. Реальный контракт нужно получить из документации своего сервиса.
Примеры рассчитаны на PowerShell 7. Проверьте $PSVersionTable.PSVersion. Параметры веб-команд и обработка ошибок отличаются от Windows PowerShell 5.1; без проверки переносить код между ними не следует.
GET с ограничением времени
$uri = 'https://api.example.org/v1/jobs?limit=100'
$headers = @{ Accept = 'application/json' }
$page = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers `
-TimeoutSec 30 -ErrorAction Stop
$page.items | Select-Object id, statusexample.org обозначает условный сервер. Замените его реальным адресом. Invoke-RestMethod преобразует JSON-ответ в объекты, поэтому искать значения регулярными выражениями в сыром тексте обычно не нужно. Значения query-параметров кодируйте через [Uri]::EscapeDataString().
JSON и авторизация
$token = $env:DEMO_API_TOKEN
if ([string]::IsNullOrWhiteSpace($token)) { throw 'Токен не задан.' }
$headers = @{ Authorization = "Bearer $token" }
$payload = @{ name = 'Тестовое задание'; options = @{ enabled = $true } }
$json = $payload | ConvertTo-Json -Depth 6
$bytes = [Text.Encoding]::UTF8.GetBytes($json)
# Запрос изменяет данные: выполняйте его только на подготовленном стенде.
Invoke-RestMethod -Uri 'https://api.example.org/v1/jobs' -Method Post `
-Headers $headers -ContentType 'application/json; charset=utf-8' `
-Body $bytes -TimeoutSec 30 -ErrorAction StopГлубина JSON должна соответствовать вложенности объекта. Не передавайте токен в URL и не выводите заголовки авторизации в журнал. Токен из переменной окружения удобен для примера; в рабочем запуске используйте механизм секретов своей платформы.
Ошибки и повторы
Отделите ошибку сети от HTTP-ошибки сервера. Для 401 проверьте срок токена, для 403 — права, для 409 — версию объекта. Повторять такие запросы без изменения условий бессмысленно. При 429 учитывайте Retry-After и лимит сервиса.
Для повторяемого чтения можно задать ограниченную политику повторов. Для POST повтор допустим только при подтверждённой идемпотентности, например с устойчивым ключом операции, который сервер действительно поддерживает. Иначе сервер мог выполнить действие, даже если клиент не получил ответ.
Пагинация без бесконечного цикла
$next = [Uri]'https://api.example.org/v1/jobs?limit=100'
$allowedHost = $next.Host
$seen = [Collections.Generic.HashSet[string]]::new()
while ($null -ne $next) {
if ($next.Scheme -ne 'https' -or $next.Host -ne $allowedHost) {
throw 'Следующая страница указывает на другой сервер.'
}
if (-not $seen.Add($next.AbsoluteUri)) { throw 'Зацикливание страниц.' }
$page = Invoke-RestMethod -Uri $next -Headers $headers -TimeoutSec 30
$page.items
if ($page.next) { $next = [Uri]::new($next, [string]$page.next) }
else { $next = $null }
}Проверка хоста защищает от отправки вашего токена на произвольный адрес из ответа. Ограничьте также число страниц и общий срок выполнения для больших выгрузок. В журнале достаточно номера страницы, количества объектов, статуса и идентификатора запроса; секреты и полные персональные данные туда не нужны.
Документация: Invoke-RestMethod.
Документация: Повторы и идемпотентность.
Иллюстрации к инструкции



Материал подготовлен самостоятельно на русском языке. Исходная тема и иллюстрации: LazyAdmin. Технические сведения сверены с документацией, указанной выше, 11 октября 2026 года. Интерфейсы и версии модулей могут отличаться от показанных примеров.