Щоб скоротити URL у PowerShell, потрібен один командлет. Invoke-RestMethod надсилає ваше призначення до API скорочувача, передає API-ключ у заголовку Bearer і повертає розібраний об'єкт, а не рядок JSON. Нічого не потрібно встановлювати на будь-якій машині, де вже є PowerShell.
Це частина серії для системних адміністраторів, яка також охоплює Python, JavaScript, C# і Go. Форму ендпойнта та модель автентифікації задокументовано в огляді безкоштовного API скорочувача URL, а маршрут дашборда наведено в загальному посібнику зі скорочення URL.
Найшвидший спосіб: один виклик Invoke-RestMethod
$headers = @{
Authorization = "Bearer $env:ELIDO_API_KEY"
'Content-Type' = 'application/json'
}
$body = @{
destination_url = 'https://example.com/spring-sale?utm_source=newsletter'
} | ConvertTo-Json
$link = Invoke-RestMethod -Method Post `
-Uri 'https://api.elido.app/v1/links' `
-Headers $headers `
-Body $body `
-TimeoutSec 10
$link.short_url # https://s.elido.me/ab12cd
Invoke-RestMethod десеріалізує відповідь, і саме це відрізняє його від Invoke-WebRequest. Кроку ConvertFrom-Json немає, як і .Content, який треба було б розгортати: $link уже є об'єктом із id і short_url.
ConvertTo-Json не є необов'язковим. Якщо передати хеш-таблицю безпосередньо в -Body, PowerShell закодує її як форму, API побачить application/x-www-form-urlencoded, і ви отримаєте помилку 400, яка виглядатиме як проблема на сервері.
Одна специфічна для PowerShell несподіванка: тут 401 або 404 - це помилка, що завершує виконання, а не значення, яке повертається. Усі інші клієнти в цій серії змушують вас перевіряти код стану, а цей - перехоплювати виняток.
Обробка помилок 429 і повторний безпечний запуск скрипту
Для будь-якого запланованого запуску потрібно додати три речі. try/catch через описану вище поведінку з помилкою. Очікування, що враховує Retry-After. І Idempotency-Key, щоб повторний запит повертав початкове посилання, а не створював друге для того самого призначення.
function Get-ShortLink {
param(
[Parameter(Mandatory)][string] $Destination,
[int] $Attempts = 3
)
# stable key: the same destination always produces the same one
$sha = [System.Security.Cryptography.SHA256]::Create()
$key = [BitConverter]::ToString(
$sha.ComputeHash([Text.Encoding]::UTF8.GetBytes($Destination))
).Replace('-', '')
$headers = @{
Authorization = "Bearer $env:ELIDO_API_KEY"
'Content-Type' = 'application/json'
'Idempotency-Key' = $key
}
$body = @{ destination_url = $Destination } | ConvertTo-Json
for ($attempt = 0; $attempt -lt $Attempts; $attempt++) {
try {
return (Invoke-RestMethod -Method Post -Uri 'https://api.elido.app/v1/links' `
-Headers $headers -Body $body -TimeoutSec 10).short_url
}
catch {
$status = $_.Exception.Response.StatusCode.value__
if ($status -eq 429) {
$wait = $_.Exception.Response.Headers['Retry-After']
if (-not $wait) { $wait = 2 } # works on 5.1 too; no ?? operator
Start-Sleep -Seconds ([int]$wait)
}
elseif ($status -ge 500) {
Start-Sleep -Seconds ([math]::Pow(2, $attempt)) # 1s, 2s, 4s
}
else {
throw # 401, 403, 422: retrying will not help
}
}
}
throw "shorten failed after $Attempts attempts"
}
У PowerShell 7 можна пропустити більшу частину дослідження винятків за допомогою -SkipHttpErrorCheck: він повертає об'єкт відповіді замість того, щоб видавати помилку, тож ви можете безпосередньо прочитати тіло помилки API. Це варто зробити, коли ви налагоджуєте 422 і хочете побачити, до якого поля API висунув претензію.
Не зберігайте ключ у скрипті
$env:ELIDO_API_KEY - найпростіша відповідь, і її достатньо для запланованого завдання з власним службовим обліковим записом. Ключ, введений у файл .ps1, для цього не підходить: він опиниться в системі контролю версій, у Get-History і в будь-якому журналі транскриптів, увімкненому у вашій інфраструктурі.
Для спільного використання кращим місцем буде модуль SecretManagement:
$env:ELIDO_API_KEY = Get-Secret -Name ElidoApiKey -AsPlainText
Тоді для ротації ключа достатньо оновити один запис у сховищі, а не шукати його у скриптах на чотирьох серверах.
Хочете запускати ці приклади без змін? Створіть ключ на безкоштовному плані, задайте $env:ELIDO_API_KEY, і все на цій сторінці працюватиме без змін.
Скорочення цілого стовпця CSV
Поширене практичне завдання - не один URL, а електронна таблиця з ними. Чотири командлети й обмеження швидкості:
$rows = Import-Csv .\campaign-urls.csv # columns: id, destination
$funcDef = ${function:Get-ShortLink}.ToString()
$done = $rows | ForEach-Object -ThrottleLimit 8 -Parallel {
$function:Get-ShortLink = $using:funcDef # ship the function into each runspace
[pscustomobject]@{
id = $_.id
destination = $_.destination
short_url = try { Get-ShortLink -Destination $_.destination }
catch { "ERROR: $($_.Exception.Message)" }
}
}
$done | Export-Csv .\campaign-urls-short.csv -NoTypeInformation
-ThrottleLimit 8 - у цьому весь секрет: одночасно виконується вісім запитів, незалежно від того, чи містить файл п'ятдесят рядків, чи п'ятдесят тисяч. Із -Parallel пов'язані дві особливості. Кожна ітерація виконується у власному runspace, тому функції та змінні з викликача невидимі, якщо не передати їх через $using:. Також потрібен PowerShell 7; у Windows PowerShell 5.1 для кількох сотень рядків найнадійнішим варіантом буде звичайний foreach.
Запис помилок у вихідний стовпець замість переривання виконання дає змогу безпечно повторити запуск. Оскільки ключ ідемпотентності походить із призначення, повторний запуск усього файлу після виправлення трьох рядків нічого не коштує й не створює дублікатів.
Вибірково перевірте результат, перш ніж щось виводити або надсилати електронною поштою. Команда curl.exe -sI https://s.elido.me/ab12cd для трьох рядків займає десять секунд і виявляє випадок, коли стовпці зсунулися на один.
Коли PowerShell - правильний інструмент
Це правильний інструмент, коли дані вже є в CSV або Active Directory, завдання запускається за розкладом у Windows або його обслуговує системний адміністратор, а не розробник застосунків. Для того, що вбудовується у застосунок, версію для C# із типізованим клієнтом та ін'єкцією залежностей легше тестувати.
У будь-якому разі потрібні: ключ зі змінної середовища або сховища, явний -TimeoutSec, try/catch навколо виклику та стабільний ключ ідемпотентності для всього, що може запуститися двічі. На сторінці API та SDK описано згенеровані клієнти, а рішення для розробників охоплює інші можливості API.
Читайте основну серію
Цей матеріал належить до інженерного кластера. Почніть із посібника з безкоштовного API скорочувача URL, а потім прочитайте про ліміти швидкості та ідемпотентність. Актуальна довідка доступна в документації API, а масовий імпорт коротких посилань із Google Sheet описує варіант без коду для такого самого завдання з CSV.
Ще в блозі
- Як скоротити URL у C# за допомогою HttpClient і .NET
- Як скоротити URL у Python за допомогою бібліотеки requests
- Масовий імпорт коротких посилань із Google Sheet
- Ліміти швидкості API скорочувача URL та ідемпотентність
- Як скорочувати URL в Excel: чотири робочі способи
- CLI скорочувача URL: скорочення посилань із термінала
Поширені запитання
Як скоротити URL у PowerShell?
Викличте Invoke-RestMethod з параметром -Method Post для ендпойнта links скорочувача, передавши API-ключ у заголовку Authorization, а призначення - у форматі JSON. Командлет сам розбирає відповідь, тож $link.short_url доступний одразу, без кроку ConvertFrom-Json.
Чи потрібен модуль, щоб скорочувати URL у PowerShell?
Ні. Invoke-RestMethod вбудований у Windows PowerShell 3.0 і кожну версію PowerShell 7, а виклик скорочувача - це один запит. Модулі варто використовувати, якщо вам потрібні обгортки у формі командлетів для багатьох ендпойнтів, а не один POST.
Чому Invoke-RestMethod видає помилку для 404 або 401?
Тому що він трактує будь-який код 4xx або 5xx як помилку, що завершує виконання, на відміну від більшості HTTP-клієнтів. Обгорніть виклик у try/catch або передайте -SkipHttpErrorCheck у PowerShell 7, щоб отримати назад об'єкт відповіді та прочитати тіло помилки, яке повернув API.
Як не зберігати API-ключ у скрипті PowerShell?
Прочитайте його зі змінної середовища за допомогою $env:ELIDO_API_KEY або збережіть у модулі SecretManagement і отримайте через Get-Secret. Ключ, вставлений у файл .ps1, опиниться в системі контролю версій, історії консолі та будь-якому ввімкненому журналі транскриптів.
Як скоротити цілий стовпець URL із CSV?
Імпортуйте файл через Import-Csv, передайте його через ForEach-Object -Parallel з -ThrottleLimit 8 і експортуйте результат через Export-Csv, додавши коротке посилання поруч з оригіналом. Обмеження швидкості не дає виконанню перевищити ліміт API; без нього великий файл запускає всі запити одночасно.
Чи працює ForEach-Object -Parallel у Windows PowerShell 5.1?
Ні, для нього потрібен PowerShell 7 або новіша версія. У 5.1 практичні варіанти - звичайний цикл foreach, якого достатньо для кількох сотень рядків, або пули runspace, якщо пакет достатньо великий, щоб виправдати додатковий код.
Спробуйте Elido
Вставте URL - отримайте коротке посилання
Без реєстрації. Посилання живе 30 днів. Зареєструйтесь, щоб зберегти назавжди.
Безкоштовно, без реєстрації · 2 на день