JSON (JavaScript Object Notation) é um formato de dados leve e amplamente utilizado para comunicação entre sistemas, especialmente em APIs REST. No PowerShell, você pode facilmente converter objetos do PowerShell em JSON e vice-versa, usando os cmdlets ConvertTo-Json e ConvertFrom-Json. Esses cmdlets são essenciais para automatizar tarefas que envolvem dados estruturados, como consumir APIs, salvar configurações ou trocar dados entre scripts.

Nesta aula, vamos explorar como usar esses cmdlets, entender o parâmetro -Depth para controlar a profundidade da serialização, criar e manipular objetos aninhados e, finalmente, integrar com APIs REST reais. Ao final, você terá uma base sólida para trabalhar com JSON em seus scripts do PowerShell.

ConvertTo-Json e ConvertFrom-Json

O cmdlet ConvertTo-Json converte um objeto do PowerShell em uma string JSON. Ele aceita qualquer objeto, incluindo hashtables, arrays e objetos personalizados. Já o cmdlet ConvertFrom-Json faz o inverso: transforma uma string JSON em um objeto do PowerShell (geralmente um PSCustomObject).

Vamos começar com um exemplo simples: criar um objeto e convertê-lo para JSON.

$pessoa = [PSCustomObject]@{
    Nome = "João"
    Idade = 30
    Cidade = "São Paulo"
}

$json = $pessoa | ConvertTo-Json
Write-Output $json

O resultado será uma string JSON com as propriedades do objeto. Agora, vamos fazer o caminho inverso: converter uma string JSON em um objeto.

$json = '{"Nome": "Maria", "Idade": 25}'
$objeto = $json | ConvertFrom-Json
Write-Output $objeto.Nome  # Exibe "Maria"

Esses cmdlets são simétricos e permitem uma conversão fácil entre os dois formatos. Note que ConvertTo-Json por padrão serializa apenas as propriedades públicas do objeto, e para hashtables, ele as trata como objetos com chaves como propriedades.

Profundidade

O parâmetro -Depth especifica quantos níveis de objetos aninhados serão incluídos na serialização. Por padrão, ConvertTo-Json serializa até 2 níveis de profundidade. Se você tiver objetos mais complexos, precisará aumentar o valor de -Depth.

Considere o exemplo a seguir com um objeto que contém um objeto aninhado:

$endereco = [PSCustomObject]@{
    Rua = "Av. Paulista"
    Numero = 1000
}

$pessoa = [PSCustomObject]@{
    Nome = "João"
    Endereco = $endereco
}

$json = $pessoa | ConvertTo-Json
Write-Output $json

O resultado será algo como:

{
    "Nome": "João",
    "Endereco": {
        "Rua": "Av. Paulista",
        "Numero": 1000
    }
}

Nesse caso, como o objeto está a 2 níveis de profundidade, o padrão já é suficiente. Mas se houver mais níveis, você precisará aumentar o valor de -Depth. Por exemplo:

$pais = [PSCustomObject]@{ Nome = "Brasil" }
$endereco = [PSCustomObject]@{ Rua = "Av. Paulista"; Pais = $pais }
$pessoa = [PSCustomObject]@{ Nome = "João"; Endereco = $endereco }

$json = $pessoa | ConvertTo-Json -Depth 3
Write-Output $json

Se você não especificar -Depth suficiente, as propriedades mais profundas serão omitidas ou convertidas em strings vazias, o que pode causar perda de dados. Por isso, é importante conhecer a estrutura dos seus objetos e ajustar a profundidade conforme necessário.

Objetos aninhados

Objetos aninhados são comuns em JSON, representando estruturas hierárquicas. No PowerShell, você pode criar objetos aninhados usando hashtables ou PSCustomObject dentro de outros objetos. Vamos ver como criar e manipular esses objetos.

Exemplo de criação de um objeto com um array de objetos aninhados:

$produtos = @(
    [PSCustomObject]@{ Nome = "Caneta"; Preco = 1.50 },
    [PSCustomObject]@{ Nome = "Caderno"; Preco = 12.90 }
)

$pedido = [PSCustomObject]@{
    Numero = 123
    Itens = $produtos
}

$json = $pedido | ConvertTo-Json -Depth 3
Write-Output $json

O JSON resultante terá um array de itens, cada um com suas propriedades. Para acessar esses objetos aninhados após o ConvertFrom-Json, você pode usar a notação de ponto ou índices:

$pedidoJson = '{"Numero": 123, "Itens": [{"Nome": "Caneta", "Preco": 1.5}, {"Nome": "Caderno", "Preco": 12.9}]}'
$pedidoObj = $pedidoJson | ConvertFrom-Json
Write-Output $pedidoObj.Itens[0].Nome  # Exibe "Caneta"

Objetos aninhados são muito úteis para representar dados complexos, como respostas de APIs que geralmente têm estruturas hierárquicas.

APIs

Uma das aplicações mais comuns do JSON no PowerShell é consumir APIs REST. O PowerShell fornece os cmdlets Invoke-RestMethod e Invoke-WebRequest para fazer chamadas HTTP. O Invoke-RestMethod automaticamente converte a resposta JSON em um objeto do PowerShell, facilitando o trabalho.

Exemplo de chamada a uma API pública (por exemplo, a API do GitHub para obter informações de um usuário):

$resposta = Invoke-RestMethod -Uri "https://api.github.com/users/octocat" -Method Get
Write-Output $resposta.login  # Exibe "octocat"
Write-Output $resposta.public_repos

Se você precisar enviar dados em JSON para uma API, pode usar o parâmetro -Body com uma string JSON, ou usar ConvertTo-Json para gerar o corpo a partir de um objeto:

$novoPost = [PSCustomObject]@{
    title = "Meu primeiro post"
    body = "Conteúdo do post"
    userId = 1
}

$jsonBody = $novoPost | ConvertTo-Json
$resposta = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -Method Post -Body $jsonBody -ContentType "application/json"
Write-Output $resposta.id

Além disso, você pode combinar ConvertFrom-Json com Invoke-WebRequest se precisar de mais controle sobre a resposta, como cabeçalhos ou status code. No entanto, Invoke-RestMethod é mais direto para manipular dados JSON.

Boas práticas

Ao trabalhar com JSON no PowerShell, considere as seguintes recomendações:

  • Sempre defina o -Depth adequado ao usar ConvertTo-Json para evitar perda de dados.
  • Valide o JSON recebido de fontes externas antes de usá-lo, especialmente se ele vier de uma API não confiável.
  • Use ConvertFrom-Json para converter respostas de APIs em objetos, facilitando o acesso às propriedades.
  • Para enviar dados, use ConvertTo-Json e especifique ContentType como application/json.
  • Considere usar Test-Json (disponível no PowerShell 6.1+) para validar se uma string é JSON válido.

Essas práticas ajudam a evitar erros comuns e a tornar seus scripts mais robustos.

Exercícios

  1. Exercício 1: Crie um objeto PowerShell representando um livro (título, autor, ano) e converta-o para JSON usando ConvertTo-Json. Exiba o JSON resultante.
  2. ✓ Resposta:
    $livro = [PSCustomObject]@{
        Titulo = "O Senhor dos Anéis"
        Autor = "J.R.R. Tolkien"
        Ano = 1954
    }
    $json = $livro | ConvertTo-Json
    Write-Output $json
    
  3. Exercício 2: Dada a string JSON '{"nome": "Ana", "idade": 28}', converta-a para um objeto e exiba o valor da propriedade nome.
  4. ✓ Resposta:
    $json = '{"nome": "Ana", "idade": 28}'
    $objeto = $json | ConvertFrom-Json
    Write-Output $objeto.nome
    
  5. Exercício 3: Crie um objeto com um array de três números e converta-o para JSON. Depois, converta o JSON de volta para um objeto e exiba o segundo elemento do array.
  6. ✓ Resposta:
    $numeros = [PSCustomObject]@{ Valores = @(10, 20, 30) }
    $json = $numeros | ConvertTo-Json
    $objeto = $json | ConvertFrom-Json
    Write-Output $objeto.Valores[1]
    
  7. Exercício 4: Use Invoke-RestMethod para consultar a API pública do JSONPlaceholder (https://jsonplaceholder.typicode.com/todos/1) e exiba o título da tarefa.
  8. ✓ Resposta:
    $resposta = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/todos/1" -Method Get
    Write-Output $resposta.title
    
  9. Exercício 5: Envie um POST para a API do JSONPlaceholder (https://jsonplaceholder.typicode.com/posts) com um objeto contendo title, body e userId (use valores fictícios). Exiba o ID retornado pela API.
  10. ✓ Resposta:
    $novoPost = [PSCustomObject]@{
        title = "Teste"
        body = "Conteúdo do teste"
        userId = 1
    }
    $jsonBody = $novoPost | ConvertTo-Json
    $resposta = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -Method Post -Body $jsonBody -ContentType "application/json"
    Write-Output $resposta.id
    

Referências