5 min di letturaIngegneria

Come accorciare un URL in PowerShell con Invoke-RestMethod

Accorcia un URL in PowerShell con un solo cmdlet, gestisci i 429, tieni la chiave API fuori dallo script e accorcia un'intera colonna CSV con ForEach-Object -Parallel.

Marius Voß
DevRel · edge infra
Come accorciare un URL in PowerShell: Invoke-RestMethod invia un URL di destinazione a un'API di URL shortening e restituisce lo short link come oggetto

Accorciare un URL in PowerShell richiede un solo cmdlet. Invoke-RestMethod invia la tua destinazione all'API dello shortener, manda la chiave API come header Bearer e restituisce un oggetto analizzato invece di una stringa JSON. Non devi installare nulla, su qualsiasi macchina che abbia già PowerShell.

Questo è l'angolo dedicato agli amministratori di sistema di una serie che copre anche Python, JavaScript, C# e Go. La struttura dell'endpoint e il modello di autenticazione sono documentati nella panoramica dell'API gratuita per URL shortener; il percorso della dashboard si trova nella guida generale su come accorciare un URL.

Il modo più rapido: una chiamata a 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 deserializza la risposta, ed è questa la differenza rispetto a Invoke-WebRequest. Non c'è alcun passaggio ConvertFrom-Json né un .Content da estrarre: $link è già un oggetto con id e short_url.

ConvertTo-Json non è facoltativo. Se passi una hashtable direttamente a -Body, PowerShell la codifica come form, l'API vede application/x-www-form-urlencoded e ottieni un 400 che sembra un problema del server.

Una sorpresa specifica di PowerShell: un 401 o un 404 qui è un errore terminale, non un valore restituito. Ogni altro client della serie ti fa controllare un codice di stato; questo ti fa intercettare un'eccezione.

Gestire i 429 e rendere lo script riutilizzabile

Per qualsiasi attività pianificata devi aggiungere tre cose. Un try/catch, a causa del comportamento che genera errori descritto sopra. Un'attesa che rispetti Retry-After. E un Idempotency-Key, così una richiesta ritentata restituisce il link originale invece di crearne un secondo per la stessa destinazione.

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"
}

Su PowerShell 7 puoi evitare gran parte dell'analisi delle eccezioni con -SkipHttpErrorCheck, che restituisce l'oggetto risposta invece di generare un errore, così puoi leggere direttamente il corpo dell'errore dell'API. È utile quando fai il debug di un 422 e vuoi vedere a quale campo l'oggetto API ha mosso un'obiezione.

PowerShell Invoke-RestMethod invia un URL di destinazione con un token Bearer e Idempotency-Key all'endpoint dei link dello shortener e restituisce un oggetto analizzato contenente short_url

Tenere la chiave fuori dallo script

$env:ELIDO_API_KEY è la risposta più semplice e basta per un'attività pianificata con il proprio account di servizio. Una chiave digitata nel file .ps1, invece, finisce nel controllo del codice sorgente, in Get-History e in qualsiasi registrazione transcript attivata nell'ambiente.

Per qualsiasi uso condiviso, il modulo SecretManagement è il posto migliore:

$env:ELIDO_API_KEY = Get-Secret -Name ElidoApiKey -AsPlainText

Ruotare una chiave significa quindi aggiornare una sola voce nel vault, invece di cercarla negli script di quattro server.

Vuoi eseguire questi esempi così come sono? Crea una chiave nel piano gratuito, imposta $env:ELIDO_API_KEY e tutto ciò che trovi in questa pagina funzionerà senza modifiche.

Accorciare un'intera colonna CSV

Il caso concreto più comune non è un singolo URL, ma un foglio di calcolo che ne contiene molti. Quattro cmdlet e un limite:

$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 è tutto il trucco: ci sono otto richieste in corso, indipendentemente dal fatto che il file abbia cinquanta righe o cinquantamila. Con -Parallel arrivano due insidie. Ogni iterazione viene eseguita nel proprio runspace, quindi funzioni e variabili del chiamante non sono visibili se non le passi con $using:. Inoltre richiede PowerShell 7; in Windows PowerShell 5.1 un semplice foreach è la risposta più onesta per qualche centinaio di righe.

Scrivere gli errori nella colonna di output invece di generarli mantiene l'esecuzione ripetibile. Poiché la chiave di idempotenza deriva dalla destinazione, rieseguire l'intero file dopo aver corretto tre righe non costa nulla e non crea duplicati.

Una pipeline PowerShell in quattro fasi che importa un CSV di destinazioni, chiama l'API dello shortener per ogni riga con un limite di richieste, esporta gli short link e controlla a campione il risultato

Controlla a campione prima che qualcosa venga stampato o inviato per email. curl.exe -sI https://s.elido.me/ab12cd su tre righe richiede dieci secondi e intercetta il caso in cui una colonna sia spostata di una posizione.

Quando PowerShell è lo strumento giusto

È lo strumento giusto quando i dati sono già in un CSV o in Active Directory, quando il job viene eseguito come attività pianificata di Windows o quando a occuparsene è un amministratore di sistema e non uno sviluppatore applicativo. Per qualsiasi cosa venga inserita in un'applicazione, la versione C# con un client tipizzato e l'iniezione delle dipendenze è più facile da testare.

In ogni caso: chiave nell'ambiente o in un vault, un -TimeoutSec esplicito, try/catch attorno alla chiamata e una chiave di idempotenza stabile per qualsiasi operazione che potrebbe essere eseguita due volte. La pagina API e SDK descrive i client generati, mentre soluzioni per sviluppatori illustra cos'altro espone l'API.

Leggi la serie Cornerstone

Questo articolo fa parte del cluster engineering. Inizia con la guida all'API gratuita per URL shortener, poi leggi rate limit e idempotenza. Il riferimento aggiornato è la documentazione dell'API, mentre importare short link in blocco da un Google Sheet illustra il percorso senza codice per lo stesso job CSV.

Articoli correlati sul blog

Domande frequenti

Come accorcio un URL in PowerShell?

Chiama Invoke-RestMethod con -Method Post sull'endpoint dei link dello shortener, passando la tua chiave API in un header Authorization e la destinazione come JSON. Il cmdlet analizza la risposta per te, quindi $link.short_url è disponibile immediatamente senza un passaggio ConvertFrom-Json.

Mi serve un modulo per accorciare gli URL in PowerShell?

No. Invoke-RestMethod è incluso in Windows PowerShell 3.0 e in ogni versione di PowerShell 7, e una chiamata allo shortener è una singola richiesta. I moduli sono utili quando vuoi wrapper con forma di cmdlet su molti endpoint anziché un solo POST.

Perché Invoke-RestMethod genera un errore su un 404 o un 401?

Perché tratta qualsiasi 4xx o 5xx come un errore terminale, l'opposto di ciò che fanno la maggior parte dei client HTTP. Avvolgi la chiamata in try/catch, oppure passa -SkipHttpErrorCheck su PowerShell 7 per ottenere nuovamente l'oggetto risposta e leggere il corpo dell'errore restituito dall'API.

Come tengo la chiave API fuori da uno script PowerShell?

Leggila da una variabile d'ambiente con $env:ELIDO_API_KEY, oppure salvala con il modulo SecretManagement e recuperala con Get-Secret. Una chiave incollata in un file .ps1 finisce nel controllo del codice sorgente, nella cronologia della console e in qualsiasi registrazione transcript attivata.

Come accorcio un'intera colonna di URL da un CSV?

Import-Csv il file, passalo attraverso ForEach-Object -Parallel con -ThrottleLimit 8 ed esegui Export-Csv sul risultato, con lo short link accanto all'originale. Il limite è ciò che mantiene l'esecuzione sotto il rate limit dell'API; senza di esso un file grande avvia tutte le richieste contemporaneamente.

ForEach-Object -Parallel funziona in Windows PowerShell 5.1?

No, richiede PowerShell 7 o versioni successive. In 5.1 le opzioni pratiche sono un semplice ciclo foreach, che va bene per qualche centinaio di righe, oppure i pool di runspace se il batch è abbastanza grande da giustificare il codice aggiuntivo.

Prova Elido

Incolla un URL, ottieni un link breve

Senza registrazione. Il link vive 30 giorni. Iscriviti per conservarlo.

Gratis, nessuna registrazione richiesta · 2 al giorno

Prova Elido

Accorciatore di URL ospitato nell'UE: domini personalizzati, analisi approfondite e API aperta. Piano gratuito - senza carta di credito.

Tag
how to shorten a url in powershell
powershell url shortener
invoke-restmethod post json
url shortener api powershell
powershell bulk shorten urls
powershell csv api script

Continua a leggere