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.
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.
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
- Cómo acortar una URL en C# con HttpClient y .NET
- Cómo acortar una URL en Python con la biblioteca requests
- Importación masiva de enlaces cortos desde una hoja de Google
- Límites de solicitudes e idempotencia de la API del acortador de URL
- Cómo acortar URL en Excel: cuatro opciones que funcionan
- CLI del acortador de URL: acorta enlaces desde la terminal
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