6 min de lectureIngénierie

Comment raccourcir une URL dans PowerShell avec Invoke-RestMethod

Raccourcissez une URL dans PowerShell avec une seule commande, gérez les erreurs 429, gardez la clé API hors du script et raccourcissez toute une colonne CSV avec ForEach-Object -Parallel.

Marius Voß
DevRel · edge infra
Comment raccourcir une URL dans PowerShell : Invoke-RestMethod envoie une URL de destination à une API de raccourcissement et renvoie le lien court sous forme d'objet

Raccourcir une URL dans PowerShell ne nécessite qu'une seule commande. Invoke-RestMethod envoie votre destination à l'API du raccourcisseur, transmet la clé API dans un en-tête Bearer et renvoie un objet analysé plutôt qu'une chaîne JSON. Rien à installer sur une machine qui dispose déjà de PowerShell.

Cet article constitue le volet dédié aux administrateurs système d'une série qui couvre également Python, JavaScript, C# et Go. La forme du point de terminaison et le modèle d'authentification sont documentés dans la présentation de l'API gratuite de raccourcissement d'URL ; l'accès au tableau de bord se trouve dans le guide général pour raccourcir une URL.

La méthode la plus rapide : un appel à 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 désérialise la réponse, ce qui le distingue de Invoke-WebRequest. Il n'y a pas d'étape ConvertFrom-Json ni de .Content à déballer : $link est déjà un objet qui contient id et short_url.

ConvertTo-Json est indispensable. Si vous transmettez directement une table de hachage à -Body, PowerShell l'encode comme un formulaire, l'API reçoit application/x-www-form-urlencoded et vous obtenez une erreur 400 qui ressemble à un problème côté serveur.

Une particularité de PowerShell peut surprendre : une réponse 401 ou 404 est ici une erreur fatale, et non une valeur renvoyée. Tous les autres clients de cette série vous font vérifier un code d'état ; celui-ci vous impose d'intercepter une exception.

Gérer les erreurs 429 et rendre le script réexécutable

Pour toute tâche planifiée, trois éléments sont à ajouter. Un bloc try/catch, à cause du comportement décrit ci-dessus. Une attente qui respecte Retry-After. Et une clé Idempotency-Key afin qu'une requête réessayée renvoie le lien d'origine au lieu d'en créer un second pour la même destination.

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

Dans PowerShell 7, vous pouvez éviter la plus grande partie de l'analyse des exceptions avec -SkipHttpErrorCheck, qui renvoie l'objet de réponse au lieu de déclencher une erreur, afin que vous puissiez lire directement le corps d'erreur de l'API. C'est utile lorsque vous déboguez une erreur 422 et voulez voir à quel champ l'API s'est opposée.

PowerShell Invoke-RestMethod envoie une URL de destination avec un jeton Bearer et une Idempotency-Key au point de terminaison de liens du raccourcisseur, puis renvoie un objet analysé contenant short_url

Garder la clé hors du script

$env:ELIDO_API_KEY est la solution la plus simple et convient pour une tâche planifiée qui dispose de son propre compte de service. En revanche, une clé saisie dans le fichier .ps1 finit dans le contrôle de version, dans Get-History et dans toute journalisation de transcription activée sur votre parc.

Pour tout ce qui est partagé, le module SecretManagement est préférable :

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

Faire tourner une clé consiste alors à mettre à jour une seule entrée du coffre plutôt qu'à fouiller des scripts sur quatre serveurs.

Vous voulez exécuter ces exemples tels quels ? Créez une clé avec l'offre gratuite, définissez $env:ELIDO_API_KEY et tout ce qui figure sur cette page fonctionnera sans modification.

Raccourcir toute une colonne CSV

La tâche courante n'est pas de traiter une seule URL, mais un tableau qui en contient beaucoup. Quatre commandes et une limitation :

$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 est tout le secret : huit requêtes en cours, que le fichier contienne cinquante lignes ou cinquante mille. Deux pièges accompagnent -Parallel. Chaque itération s'exécute dans son propre runspace : les fonctions et variables de l'appelant ne sont donc pas visibles, sauf si vous les transmettez avec $using:. Et cette option nécessite PowerShell 7 ; dans Windows PowerShell 5.1, une simple boucle foreach est la réponse honnête pour quelques centaines de lignes.

Écrire les erreurs dans la colonne de sortie au lieu de les déclencher permet de réexécuter le traitement. Comme la clé d'idempotence est dérivée de la destination, relancer tout le fichier après avoir corrigé trois lignes ne coûte rien et ne crée aucun doublon.

Pipeline PowerShell en quatre étapes : importer un CSV de destinations, appeler l'API du raccourcisseur pour chaque ligne avec une limitation, exporter les liens courts et vérifier un échantillon du résultat

Vérifiez un échantillon avant toute impression ou tout envoi par e-mail. curl.exe -sI https://s.elido.me/ab12cd sur trois lignes prend dix secondes et détecte le cas où une colonne aurait été décalée d'une position.

Quand PowerShell est le bon outil

C'est le bon outil lorsque les données se trouvent déjà dans un CSV ou Active Directory, lorsque la tâche s'exécute dans le planificateur de tâches Windows ou lorsque la personne qui la maintient est un administrateur système plutôt qu'un développeur d'applications. Pour tout ce qui est intégré à une application, la version C# avec un client typé et l'injection de dépendances est plus facile à tester.

Dans tous les cas : une clé provenant de l'environnement ou d'un coffre, un -TimeoutSec explicite, un bloc try/catch autour de l'appel et une clé d'idempotence stable pour tout ce qui peut être exécuté deux fois. La page API et SDK présente les clients générés, et les solutions pour développeurs couvre les autres possibilités exposées par l'API.

Lire la série de référence

Cet article appartient au cluster engineering. Commencez par le guide de l'API gratuite de raccourcissement d'URL, puis consultez les limites de débit et l'idempotence. La référence en ligne se trouve dans la documentation de l'API, et l'importation en masse de liens courts depuis une feuille Google présente la méthode sans code pour ce même traitement CSV.

Sur le même sujet sur le blog

Questions fréquentes

Comment raccourcir une URL dans PowerShell ?

Appelez Invoke-RestMethod avec -Method Post sur le point de terminaison de liens du raccourcisseur, en transmettant votre clé API dans un en-tête Authorization et la destination au format JSON. La commande analyse la réponse pour vous : $link.short_url est donc immédiatement disponible, sans étape ConvertFrom-Json.

Ai-je besoin d'un module pour raccourcir des URL dans PowerShell ?

Non. Invoke-RestMethod est intégré à Windows PowerShell 3.0 et à toutes les versions de PowerShell 7, et un appel au raccourcisseur ne nécessite qu'une seule requête. Les modules sont utiles lorsque vous voulez des wrappers prenant la forme de commandes sur de nombreux points de terminaison plutôt que pour un seul POST.

Pourquoi Invoke-RestMethod échoue-t-il avec une erreur 404 ou 401 ?

Parce qu'il traite toute réponse 4xx ou 5xx comme une erreur fatale, ce qui est l'inverse du comportement de la plupart des clients HTTP. Entourez l'appel d'un bloc try/catch, ou transmettez -SkipHttpErrorCheck dans PowerShell 7 pour récupérer l'objet de réponse et lire le corps d'erreur renvoyé par l'API.

Comment garder la clé API hors d'un script PowerShell ?

Lisez-la depuis une variable d'environnement avec $env:ELIDO_API_KEY, ou stockez-la avec le module SecretManagement et récupérez-la avec Get-Secret. Une clé collée dans un fichier .ps1 finit dans le contrôle de version, l'historique de la console et toute journalisation de transcription activée.

Comment raccourcir toute une colonne d'URL provenant d'un fichier CSV ?

Import-Csv le fichier, faites-le passer par ForEach-Object -Parallel avec -ThrottleLimit 8, puis utilisez Export-Csv pour écrire le résultat avec le lien court à côté de l'original. La limitation est ce qui maintient l'exécution sous la limite de débit de l'API ; sans elle, un fichier volumineux démarre toutes les requêtes en même temps.

ForEach-Object -Parallel fonctionne-t-il dans Windows PowerShell 5.1 ?

Non, il nécessite PowerShell 7 ou une version ultérieure. En 5.1, les options pratiques sont une simple boucle foreach, qui convient pour quelques centaines de lignes, ou des pools de runspaces si le lot est assez important pour justifier le code supplémentaire.

Essayer Elido

Collez une URL, obtenez un lien court

Sans inscription. Lien actif 30 jours. Inscrivez-vous pour le garder pour toujours.

Gratuit, sans inscription · 2 par jour

Essayer Elido

Raccourcisseur d'URL hébergé en UE : domaines personnalisés, analyses approfondies et API ouverte. Forfait gratuit - sans carte bancaire.

Tags
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

Lire la suite