Requisições web
Nesta aula, você aprenderá a fazer requisições web no PowerShell usando Invoke-WebRequest e Invoke-RestMethod, explorará o consumo de APIs REST e implementará autenticação básica. Ao final, terá uma base sólida para integrar serviços web em seus scripts.
Nesta aula, vamos explorar como o PowerShell pode interagir com a web, realizando requisições HTTP para obter dados, enviar informações e consumir APIs REST. Essa habilidade é essencial para automatizar tarefas que dependem de serviços online, como consultar informações de sistemas, integrar com serviços de terceiros ou até mesmo monitorar a saúde de aplicações.
Dominar requisições web no PowerShell permite que você crie scripts poderosos que se comunicam com o mundo exterior. Veremos dois cmdlets principais: Invoke-WebRequest e Invoke-RestMethod, cada um com suas particularidades. Também abordaremos a autenticação básica para acessar recursos protegidos, um requisito comum em ambientes corporativos.
Invoke-WebRequest
O cmdlet Invoke-WebRequest é a ferramenta mais versátil para interagir com a web no PowerShell. Ele envia uma solicitação HTTP e retorna uma resposta detalhada, incluindo o conteúdo, cabeçalhos, status e outras informações. Isso é útil quando você precisa de controle fino sobre a resposta ou deseja lidar com HTML, imagens ou outros tipos de conteúdo.
A sintaxe básica é simples: Invoke-WebRequest -Uri 'https://exemplo.com'. O resultado é um objeto BasicHtmlWebResponseObject que contém propriedades como Content, StatusCode, Headers e BaseResponse. Vamos ver um exemplo prático:
$resposta = Invoke-WebRequest -Uri 'https://jsonplaceholder.typicode.com/posts/1'
$resposta.StatusCode # 200
$resposta.Content # Corpo da resposta (JSON ou HTML)
$resposta.Headers['Content-Type'] # Tipo de conteúdoVocê pode usar parâmetros como -Method para especificar o verbo HTTP (GET, POST, PUT, DELETE), -Headers para enviar cabeçalhos personalizados e -Body para incluir dados no corpo da solicitação. Por exemplo, para fazer um POST com JSON:
$corpo = @{ titulo = 'Novo Post'; conteudo = 'Conteúdo do post' } | ConvertTo-Json
Invoke-WebRequest -Uri 'https://jsonplaceholder.typicode.com/posts' -Method Post -Body $corpo -ContentType 'application/json'Uma observação importante: Invoke-WebRequest retorna o conteúdo como string. Se você estiver trabalhando com APIs que retornam JSON, pode ser mais conveniente usar Invoke-RestMethod, que já converte automaticamente.
Invoke-RestMethod
O cmdlet Invoke-RestMethod é especializado em consumir APIs REST. Ele envia a requisição e automaticamente converte a resposta JSON (ou XML) em objetos PowerShell, facilitando a manipulação dos dados. Isso elimina a necessidade de converter manualmente o conteúdo com ConvertFrom-Json.
Por exemplo, ao consultar uma API que retorna uma lista de posts, você obtém uma coleção de objetos com propriedades diretamente acessíveis:
$posts = Invoke-RestMethod -Uri 'https://jsonplaceholder.typicode.com/posts'
$posts[0].title # Acessa o título do primeiro post
$posts.Count # Número de postsAlém disso, Invoke-RestMethod aceita os mesmos parâmetros de Invoke-WebRequest (como -Method, -Headers, -Body), mas o tratamento da resposta é mais amigável. É a escolha ideal para scripts que consomem APIs JSON.
Um exemplo mais completo, incluindo envio de dados:
$novoPost = @{ title = 'PowerShell é demais'; body = 'Aprendendo Invoke-RestMethod'; userId = 1 }
$resultado = Invoke-RestMethod -Uri 'https://jsonplaceholder.typicode.com/posts' -Method Post -Body ($novoPost | ConvertTo-Json) -ContentType 'application/json'
$resultado.id # ID do novo post criadoAPIs REST
APIs REST (Representational State Transfer) são um estilo arquitetônico para criar serviços web. Elas usam HTTP e seus verbos (GET, POST, PUT, DELETE) para operações CRUD (Create, Read, Update, Delete). No PowerShell, consumir APIs REST é direto com Invoke-RestMethod.
Vamos entender os principais conceitos:
- Recursos: São identificados por URLs, por exemplo,
https://api.exemplo.com/usuarios. - Verbos HTTP: Indicam a ação desejada: GET (ler), POST (criar), PUT (atualizar), DELETE (remover).
- Status codes: A resposta inclui um código (200 OK, 201 Created, 404 Not Found, 500 Internal Server Error).
- JSON/XML: Geralmente, os dados são trocados nesses formatos.
Para lidar com APIs que exigem parâmetros na URL (query strings), você pode usar o parâmetro -Body com um dicionário para GET ou simplesmente incluir na URL. Exemplo:
$parametros = @{ userId = 1 }
$posts = Invoke-RestMethod -Uri 'https://jsonplaceholder.typicode.com/posts' -Body $parametros
$posts | ForEach-Object { $_.title }É importante tratar erros: use try/catch para capturar exceções de rede ou respostas com status de erro. O PowerShell lança uma exceção quando o status não é 2xx. Você pode inspecionar $_.Exception.Response.StatusCode para obter o código.
try {
$dados = Invoke-RestMethod -Uri 'https://api.exemplo.com/recurso'
} catch {
Write-Host "Erro: $($_.Exception.Message)"
if ($_.Exception.Response) {
Write-Host "Status: $($_.Exception.Response.StatusCode)"
}
}Autenticação básica
Muitas APIs exigem autenticação. A autenticação básica (Basic Auth) é um método simples em que o cliente envia o nome de usuário e senha codificados em Base64 no cabeçalho Authorization. No PowerShell, você pode criar o cabeçalho manualmente ou usar o parâmetro -Credential.
Para usar -Credential, você precisa de um objeto PSCredential. Você pode obtê-lo com Get-Credential ou criá-lo diretamente:
$usuario = 'admin'
$senha = '123456'
$credencial = [PSCredential]::new($usuario, ($senha | ConvertTo-SecureString -AsPlainText -Force))
Invoke-RestMethod -Uri 'https://api.exemplo.com/dados' -Credential $credencialInternamente, o PowerShell converte essas credenciais para o cabeçalho correto. Se você precisar de mais controle, pode montar o cabeçalho manualmente:
$par = "$usuario`:$senha"
$base64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($par))
$headers = @{ Authorization = "Basic $base64" }
Invoke-RestMethod -Uri 'https://api.exemplo.com/dados' -Headers $headersÉ crucial nunca armazenar senhas em texto plano nos scripts. Prefira usar Get-Credential para solicitar interativamente ou gerenciar segredos com o módulo Microsoft.PowerShell.SecretManagement.
Boas práticas e observações finais
Ao trabalhar com requisições web, siga estas boas práticas:
- Sempre valide os parâmetros e a URL para evitar injeção de comandos.
- Use
try/catchpara tratamento de erros robusto. - Prefira
Invoke-RestMethodpara APIs JSON, pois simplifica o código. - Respeite os limites de taxa das APIs e implemente pausas quando necessário.
- Nunca exponha credenciais em logs ou saídas de script.
Referências
- Documentação oficial do Invoke-WebRequest
- Documentação oficial do Invoke-RestMethod
- Autenticação HTTP (MDN)
- REST API Tutorial
- JSONPlaceholder - API fake para testes
- Tudo sobre PSCustomObject (PowerShell)
Exercícios
- Exercício 1: Use
Invoke-WebRequestpara baixar o conteúdo da páginahttps://example.come exiba o status code e o tamanho do conteúdo. - Exercício 2: Consulte a API
https://jsonplaceholder.typicode.com/usersusandoInvoke-RestMethode liste todos os nomes de usuários. - Exercício 3: Envie um POST para
https://jsonplaceholder.typicode.com/postscom um título e corpo de sua escolha, usandoInvoke-RestMethod, e exiba o ID retornado. - Exercício 4: Implemente autenticação básica manualmente, enviando um cabeçalho
Authorizationcodificado em Base64 para uma URL fictícia (ex.:https://httpbin.org/basic-auth/user/pass). Use usuário 'user' e senha 'pass'. - Exercício 5: Escreva um script que faça uma requisição GET para
https://jsonplaceholder.typicode.com/posts/1e trate erros caso a API não esteja acessível.
$resposta = Invoke-WebRequest -Uri 'https://example.com'
Write-Host "Status: $($resposta.StatusCode)"
Write-Host "Tamanho do conteúdo: $($resposta.Content.Length)"$usuarios = Invoke-RestMethod -Uri 'https://jsonplaceholder.typicode.com/users'
$usuarios | ForEach-Object { $_.name }$post = @{ title = 'Meu primeiro post'; body = 'Conteúdo do post'; userId = 1 }
$novo = Invoke-RestMethod -Uri 'https://jsonplaceholder.typicode.com/posts' -Method Post -Body ($post | ConvertTo-Json) -ContentType 'application/json'
Write-Host "ID criado: $($novo.id)"$usuario = 'user'
$senha = 'pass'
$par = "$usuario`:$senha"
$base64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($par))
$headers = @{ Authorization = "Basic $base64" }
$resposta = Invoke-RestMethod -Uri 'https://httpbin.org/basic-auth/user/pass' -Headers $headers
$resposta | ConvertTo-Jsontry {
$post = Invoke-RestMethod -Uri 'https://jsonplaceholder.typicode.com/posts/1'
Write-Host "Título: $($post.title)"
} catch {
Write-Host "Erro na requisição: $($_.Exception.Message)"
if ($_.Exception.Response) {
Write-Host "Status code: $($_.Exception.Response.StatusCode)"
}
}