Encurtar uma URL no PowerShell exige um único cmdlet. Invoke-RestMethod envia seu destino para a API do encurtador, manda a chave de API como um cabeçalho Bearer e devolve um objeto analisado, em vez de uma string de JSON. Não há nada para instalar em qualquer máquina que já tenha PowerShell.
Este é o capítulo de administração de sistemas de uma série que também aborda Python, JavaScript, C# e Go. O formato do endpoint e o modelo de autenticação estão documentados na visão geral da API gratuita de encurtador de URLs; a rota do painel está no guia geral sobre como encurtar uma URL.
A Maneira Mais Rápida: Uma Chamada 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 desserializa a resposta, e essa é a diferença entre ele e Invoke-WebRequest. Não há uma etapa ConvertFrom-Json nem um .Content para desembrulhar: $link já é um objeto com id e short_url.
ConvertTo-Json não é opcional. Se você passar uma tabela hash diretamente para -Body, o PowerShell a codifica como formulário, a API recebe application/x-www-form-urlencoded e você obtém um 400 que parece um problema do servidor.
Uma surpresa específica do PowerShell: um 401 ou 404 é um erro terminante aqui, não um valor de retorno. Todos os outros clientes desta série fazem você verificar um código de status; este faz você capturar uma exceção.
Trate os 429 e Mantenha o Script Reexecutável
Para qualquer tarefa agendada, é preciso adicionar três coisas. Um try/catch, por causa do comportamento de geração de erros mencionado acima. Uma espera que respeite Retry-After. E uma Idempotency-Key, para que uma requisição repetida retorne o link original em vez de criar um segundo para o mesmo 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"
}
No PowerShell 7, você pode evitar a maior parte da investigação de exceções com -SkipHttpErrorCheck, que retorna o objeto de resposta em vez de gerar um erro, para que você possa ler diretamente o corpo de erro da API. Vale a pena fazer isso ao depurar um 422 e querer ver qual campo gerou a objeção da API.
Mantenha a Chave Fora do Script
$env:ELIDO_API_KEY é a resposta mais simples e é suficiente para uma tarefa agendada com sua própria conta de serviço. Uma chave digitada no arquivo .ps1, não: ela vai parar no controle de versão, em Get-History e em qualquer registro de transcrição que esteja ativado no ambiente.
Para qualquer coisa compartilhada, o módulo SecretManagement é um lugar melhor:
$env:ELIDO_API_KEY = Get-Secret -Name ElidoApiKey -AsPlainText
Rotacionar uma chave passa a significar atualizar uma única entrada do cofre, em vez de procurá-la em scripts de quatro servidores.
Quer executar tudo como está escrito? Crie uma chave no plano gratuito, defina $env:ELIDO_API_KEY e tudo nesta página funcionará sem alterações.
Encurte uma Coluna Inteira de CSV
A tarefa real mais comum não é uma URL, mas uma planilha cheia delas. Quatro cmdlets e um 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 é todo o segredo: oito requisições em andamento, independentemente de o arquivo ter cinquenta linhas ou cinquenta mil. -Parallel traz duas armadilhas. Cada iteração é executada em seu próprio runspace, então as funções e variáveis do chamador não ficam visíveis a menos que você as passe com $using:. E ele requer o PowerShell 7; no Windows PowerShell 5.1, um foreach comum é a resposta honesta para algumas centenas de linhas.
Escrever os erros na coluna de saída em vez de gerar um erro mantém a execução reexecutável. Como a chave de idempotência é derivada do destino, executar o arquivo inteiro novamente depois de corrigir três linhas não custa nada nem cria duplicatas.
Faça uma verificação pontual antes de qualquer coisa ser impressa ou enviada por e-mail. curl.exe -sI https://s.elido.me/ab12cd em três linhas leva dez segundos e detecta o caso em que uma coluna ficou deslocada uma posição.
Quando o PowerShell é a Ferramenta Certa
Ele é a ferramenta certa quando os dados já estão em um CSV ou no Active Directory, quando o trabalho é executado em uma tarefa agendada do Windows ou quando a pessoa que o mantém é um administrador de sistemas, e não um desenvolvedor de aplicações. Para qualquer coisa que seja distribuída dentro de uma aplicação, a versão em C# com um cliente tipado e injeção de dependência é mais fácil de testar.
De qualquer forma: chave vinda do ambiente ou de um cofre, um -TimeoutSec explícito, try/catch ao redor da chamada e uma chave de idempotência estável em qualquer coisa que possa ser executada duas vezes. A página de API e SDKs aborda os clientes gerados, e soluções para desenvolvedores mostra o que mais a API oferece.
Leia a Série Principal
Este artigo está no cluster de engenharia. Comece pelo guia da API gratuita de encurtador de URLs e depois leia limites de requisições e idempotência. A referência atualizada está na documentação da API, e importe links curtos em massa de uma Planilha Google aborda o caminho sem código para o mesmo trabalho com CSV.
Relacionado no Blog
- Como encurtar uma URL em C# com HttpClient e .NET
- Como encurtar uma URL em Python com a biblioteca requests
- Importe links curtos em massa de uma Planilha Google
- Limites de requisições e idempotência da API do encurtador de URLs
- Como encurtar URLs no Excel: quatro caminhos que funcionam
- CLI de encurtador de URLs: encurte links no terminal
Perguntas frequentes
Como encurto uma URL no PowerShell?
Chame Invoke-RestMethod com -Method Post no endpoint de links do encurtador, passando sua chave de API em um cabeçalho Authorization e o destino como JSON. O cmdlet analisa a resposta para você, então $link.short_url fica disponível imediatamente, sem uma etapa ConvertFrom-Json.
Preciso de um módulo para encurtar URLs no PowerShell?
Não. Invoke-RestMethod vem integrado ao Windows PowerShell 3.0 e a todas as versões do PowerShell 7, e uma chamada ao encurtador é uma única requisição. Módulos valem a pena quando você quer wrappers no formato de cmdlets para muitos endpoints, em vez de um único POST.
Por que Invoke-RestMethod gera um erro em um 404 ou 401?
Porque ele trata qualquer 4xx ou 5xx como um erro terminante, o oposto do comportamento da maioria dos clientes HTTP. Envolva a chamada em try/catch ou passe -SkipHttpErrorCheck no PowerShell 7 para receber o objeto de resposta e ler o corpo do erro retornado pela API.
Como mantenho a chave de API fora de um script do PowerShell?
Leia-a de uma variável de ambiente com $env:ELIDO_API_KEY ou armazene-a com o módulo SecretManagement e busque-a com Get-Secret. Uma chave colada em um arquivo .ps1 acaba no controle de versão, no histórico do console e em qualquer registro de transcrição que esteja ativado.
Como encurto uma coluna inteira de URLs de um CSV?
Use Import-Csv no arquivo, envie-o por ForEach-Object -Parallel com -ThrottleLimit 8 e use Export-Csv no resultado, com o link curto ao lado do original. O limite é o que mantém a execução dentro do limite de requisições da API; sem ele, um arquivo grande inicia todas as requisições ao mesmo tempo.
ForEach-Object -Parallel funciona no Windows PowerShell 5.1?
Não, ele requer o PowerShell 7 ou posterior. No 5.1, as opções práticas são um loop foreach comum, que funciona bem para algumas centenas de linhas, ou pools de runspaces, se o lote for grande o bastante para justificar o código adicional.
Experimente Elido
Cole uma URL, obtenha um link curto
Sem cadastro. O link vive 30 dias. Cadastre-se para mantê-lo para sempre.
Grátis, sem necessidade de registo · 2 por dia