6 min de lecturaIngeniería

Cómo acortar una URL en PowerShell con Invoke-RestMethod

Acorta una URL en PowerShell con un solo cmdlet, gestiona los errores 429, mantén la clave de API fuera del script y acorta una columna CSV completa con ForEach-Object -Parallel.

Marius Voß
DevRel · edge infra
Cómo acortar una URL en PowerShell: Invoke-RestMethod envía una URL de destino a una API de acortamiento y devuelve el enlace corto como un objeto

Acortar una URL en PowerShell requiere un solo cmdlet. Invoke-RestMethod envía tu destino a la API del acortador, manda la clave de API como una cabecera Bearer y devuelve un objeto analizado en lugar de una cadena JSON. No tienes que instalar nada en ninguna máquina que ya tenga PowerShell.

Esta es la sección para administradores de sistemas de una serie que también cubre Python, JavaScript, C# y Go. La forma del endpoint y el modelo de autenticación están documentados en la guía general de la API gratuita del acortador de URL; la ruta del panel está en la guía general sobre cómo acortar una URL.

La forma más rápida: una llamada 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 deserializa la respuesta, que es la diferencia con Invoke-WebRequest. No hay ningún paso de ConvertFrom-Json ni ningún .Content que desenvolver: $link ya es un objeto con id y short_url.

ConvertTo-Json no es opcional. Si pasas una tabla hash directamente a -Body, PowerShell la codifica como un formulario, la API ve application/x-www-form-urlencoded y obtienes un 400 que parece un problema del servidor.

Una sorpresa específica de PowerShell: aquí un 401 o un 404 es un error terminante, no un valor de retorno. Todos los demás clientes de esta serie te hacen comprobar un código de estado; este te hace capturar una excepción.

Gestiona los errores 429 y haz que el script se pueda volver a ejecutar

Para cualquier tarea programada hay que añadir tres cosas. Un try/catch, por el comportamiento descrito arriba. Una espera que respete Retry-After. Y una Idempotency-Key para que una solicitud reintentada devuelva el enlace original en lugar de crear otro para el mismo destino.

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

En PowerShell 7 puedes evitar gran parte de la investigación de excepciones con -SkipHttpErrorCheck, que devuelve el objeto de respuesta en lugar de lanzar un error para que puedas leer directamente el cuerpo del error de la API. Merece la pena hacerlo cuando depuras un 422 y quieres ver qué campo rechazó la API.

PowerShell Invoke-RestMethod envía una URL de destino con un token Bearer y una Idempotency-Key al endpoint de enlaces del acortador y devuelve un objeto analizado que contiene short_url

Mantén la clave fuera del script

$env:ELIDO_API_KEY es la respuesta sencilla y basta para una tarea programada con su propia cuenta de servicio. Una clave escrita en el archivo .ps1 no sirve: acaba en el control de versiones, en Get-History y en cualquier registro de transcripción que esté activado en el entorno.

Para cualquier cosa compartida, el módulo SecretManagement es un lugar mejor:

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

Rotar una clave significa entonces actualizar una entrada del almacén en lugar de buscarla en scripts de cuatro servidores.

¿Quieres ejecutar estos ejemplos tal cual? Crea una clave en el plan gratuito, establece $env:ELIDO_API_KEY y todo lo de esta página funcionará sin cambios.

Acorta una columna CSV completa

La tarea real más habitual no es una URL, sino una hoja de cálculo llena de ellas. Cuatro cmdlets y un límite:

$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 es todo el truco: hay ocho solicitudes en curso independientemente de que el archivo tenga cincuenta filas o cincuenta mil. -Parallel trae dos particularidades. Cada iteración se ejecuta en su propio runspace, así que las funciones y variables de quien llama no están visibles a menos que las pases con $using:. Además, necesita PowerShell 7; en Windows PowerShell 5.1, un foreach normal es la respuesta honesta para unos cientos de filas.

Escribir los errores en la columna de salida en lugar de lanzar una excepción permite volver a ejecutar el proceso. Como la clave de idempotencia se deriva del destino, volver a ejecutar todo el archivo después de corregir tres filas no cuesta nada ni crea duplicados.

Una canalización de PowerShell en cuatro etapas que importa un CSV de destinos, llama a la API del acortador por fila con un límite de solicitudes, exporta los enlaces cortos y comprueba algunas filas

Comprueba algunas filas antes de imprimir o enviar nada por correo. curl.exe -sI https://s.elido.me/ab12cd en tres filas tarda diez segundos y detecta el caso en que una columna se desplazó una posición.

Cuándo PowerShell es la herramienta adecuada

Es la herramienta adecuada cuando los datos ya están en un CSV o en Active Directory, cuando el trabajo se ejecuta como una tarea programada de Windows o cuando quien lo mantiene es un administrador de sistemas y no un desarrollador de aplicaciones. Para cualquier cosa que se integre en una aplicación, la versión de C# con un cliente tipado e inyección de dependencias es más fácil de probar.

En cualquier caso: usa la clave desde el entorno o un almacén, un -TimeoutSec explícito, try/catch alrededor de la llamada y una clave de idempotencia estable en todo lo que pueda ejecutarse dos veces. La página de la API y los SDK cubre los clientes generados y las soluciones para desarrolladores cubre qué más expone la API.

Lee la serie insignia

Esto pertenece al clúster de ingeniería. Empieza con la guía de la API gratuita del acortador de URL y después consulta límites de solicitudes e idempotencia. La referencia actual es la documentación de la API, y la importación masiva de enlaces cortos desde una hoja de Google cubre la opción sin código para el mismo trabajo con CSV.

Relacionado en el blog

Preguntas frecuentes

¿Cómo acorto una URL en PowerShell?

Llama a Invoke-RestMethod con -Method Post contra el endpoint de enlaces del acortador, pasando tu clave de API en una cabecera Authorization y el destino como JSON. El cmdlet analiza la respuesta por ti, así que $link.short_url está disponible de inmediato sin un paso de ConvertFrom-Json.

¿Necesito un módulo para acortar URL en PowerShell?

No. Invoke-RestMethod viene integrado en Windows PowerShell 3.0 y en todas las versiones de PowerShell 7, y una llamada al acortador es una sola solicitud. Los módulos merecen la pena cuando quieres envoltorios con forma de cmdlet para muchos endpoints, no para un solo POST.

¿Por qué Invoke-RestMethod lanza un error con un 404 o un 401?

Porque trata cualquier 4xx o 5xx como un error terminante, al contrario que la mayoría de los clientes HTTP. Envuelve la llamada en try/catch o pasa -SkipHttpErrorCheck en PowerShell 7 para recuperar el objeto de respuesta y poder leer el cuerpo del error que devolvió la API.

¿Cómo mantengo la clave de API fuera de un script de PowerShell?

Léela desde una variable de entorno con $env:ELIDO_API_KEY o guárdala con el módulo SecretManagement y recupérala con Get-Secret. Una clave pegada en un archivo .ps1 acaba en el control de versiones, en el historial de la consola y en cualquier registro de transcripción que esté activado.

¿Cómo acorto una columna completa de URL desde un CSV?

Import-Csv el archivo, pásalo por ForEach-Object -Parallel con -ThrottleLimit 8 y exporta el resultado con Export-Csv, con el enlace corto junto al original. El límite es lo que mantiene la ejecución por debajo del límite de solicitudes de la API; sin él, un archivo grande inicia todas las solicitudes a la vez.

¿Funciona ForEach-Object -Parallel en Windows PowerShell 5.1?

No, necesita PowerShell 7 o posterior. En 5.1, las opciones prácticas son un bucle foreach normal, que va bien para unos cientos de filas, o grupos de runspaces si el lote es lo bastante grande como para justificar el código adicional.

Prueba Elido

Pega una URL, obtén un enlace corto

Sin registro. El enlace vive 30 días. Crea una cuenta para conservarlo.

Gratis, sin registro · 2 por día

Prueba Elido

Acortador de URL alojado en la UE: dominios personalizados, análisis profundo y API abierta. Plan gratuito - sin tarjeta de crédito.

Etiquetas
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

Seguir leyendo