Nesta aula, vamos construir um projeto completo de geração de relatório HTML usando PowerShell. Você aprenderá a coletar dados de forma eficiente, convertê-los para HTML, aplicar estilos profissionais e exportar o resultado final. Este projeto é útil para administradores de sistemas que precisam gerar relatórios periódicos de forma automatizada.

O PowerShell oferece uma integração poderosa com HTML, permitindo transformar qualquer objeto em uma página web estruturada. Vamos explorar desde a coleta de dados até a estilização, criando um relatório de processos que pode ser facilmente adaptado para outros cenários, como inventário de hardware, monitoramento de serviços ou análise de logs.

Coleta de dados

O primeiro passo para criar um relatório é coletar os dados que serão exibidos. No PowerShell, a maioria dos cmdlets retorna objetos que podem ser manipulados e formatados. Para o nosso projeto, vamos coletar informações sobre os processos em execução no sistema, usando o cmdlet Get-Process. Esse cmdlet retorna objetos do tipo System.Diagnostics.Process, que contêm propriedades como Name, Id, CPU, WorkingSet, entre outras.

É importante filtrar e selecionar apenas as propriedades relevantes para o relatório, a fim de evitar poluição visual. Podemos usar o cmdlet Select-Object para escolher as colunas que desejamos exibir. Além disso, podemos ordenar os dados com Sort-Object para facilitar a leitura. Por exemplo, vamos selecionar os 10 processos que mais consomem memória:

$processos = Get-Process |
    Sort-Object -Property WorkingSet -Descending |
    Select-Object -First 10 -Property Name, Id, CPU, WorkingSet

Nesse trecho, $processos armazenará uma coleção de objetos com as propriedades selecionadas. Observe que usamos WorkingSet (memória em bytes) para ordenar. Para melhorar a legibilidade, podemos converter essa informação para megabytes (MB) usando um cálculo simples dentro do próprio pipeline:

$processos = Get-Process |
    Sort-Object -Property WorkingSet -Descending |
    Select-Object -First 10 -Property Name, Id, CPU, @{Name='Memória (MB)'; Expression={[math]::Round($_.WorkingSet / 1MB, 2)}}

Essa técnica de criar propriedades calculadas é muito útil para formatar dados de forma amigável. Agora temos uma lista de processos pronta para ser transformada em HTML.

ConvertTo-Html

O cmdlet ConvertTo-Html é a ferramenta central para gerar HTML a partir de objetos. Ele converte qualquer coleção de objetos em uma tabela HTML, mas também permite personalizar a estrutura da página, como título, cabeçalho e até mesmo conteúdo adicional. A sintaxe básica é:

$html = $processos | ConvertTo-Html -Property Name, Id, CPU, 'Memória (MB)' -Title "Relatório de Processos"

No exemplo acima, especificamos as propriedades que devem ser incluídas na tabela e definimos o título da página. Porém, o resultado é apenas um fragmento HTML sem as tags básicas de documento. Para criar uma página completa, precisamos usar os parâmetros -Head, -Body e -Title. Podemos também usar o parâmetro -CssUri para apontar para um arquivo CSS externo, mas para um relatório autônomo, é melhor embutir o CSS diretamente no cabeçalho.

Vamos construir um documento HTML completo. Primeiro, definimos um cabeçalho com CSS personalizado:

$head = @'

'@

Em seguida, usamos ConvertTo-Html com o parâmetro -Head para incluir esse CSS:

$html = $processos | ConvertTo-Html -Head $head -Title "Relatório de Processos"

O resultado é uma string contendo o HTML completo, incluindo <html>, <head> e <body>. Para verificar, podemos exibir no console ou salvar em arquivo. Mais adiante veremos como exportar.

É importante notar que ConvertTo-Html gera uma tabela com base nas propriedades dos objetos. Se algum valor for nulo ou vazio, ele aparecerá como uma célula vazia. Podemos pré-processar os dados para substituir valores nulos por algo como "N/A" se necessário.

Estilização

Um relatório profissional não se resume a uma tabela simples; ele precisa de uma aparência agradável e consistente. O PowerShell permite injetar CSS diretamente no HTML gerado, como fizemos no exemplo anterior. Vamos aprimorar a estilização para tornar o relatório mais atrativo, com cores, sombras e melhor espaçamento.

Podemos também adicionar um cabeçalho personalizado com o título e a data de geração, além de um rodapé. Para isso, usamos o parâmetro -PreContent e -PostContent do ConvertTo-Html. Esses parâmetros permitem inserir HTML antes e depois da tabela, respectivamente.

Vamos criar um cabeçalho com o título e a data:

$data = Get-Date -Format "dd/MM/yyyy HH:mm"
$preContent = "

Relatório de Processos

Gerado em: $data

" $html = $processos | ConvertTo-Html -Head $head -PreContent $preContent -Title "Relatório de Processos"

Com isso, o relatório terá um título e a data de geração. Podemos também adicionar um rodapé com informações adicionais, como o nome do administrador ou um link para documentação.

Para uma estilização mais avançada, podemos usar frameworks como Bootstrap ou até mesmo CSS customizado com gradientes e animações. O PowerShell não limita o que você pode incluir no cabeçalho. Por exemplo, para usar Bootstrap, basta incluir o link CDN no -Head:

$head = @'

'@

Com isso, as tabelas terão as classes do Bootstrap se você adicioná-las via -TableClass (parâmetro que permite especificar classes CSS para a tabela). Mas lembre-se de que o relatório deve ser autocontido, então é melhor embutir o CSS ou usar um arquivo local.

Exportação

Depois de gerar o HTML, o próximo passo é exportá-lo para um arquivo. O cmdlet Out-File é o mais simples para salvar o conteúdo em um arquivo de texto. Precisamos garantir que a codificação seja adequada (UTF-8) para suportar caracteres especiais, como acentos. O PowerShell 5.1 usa UTF-16 por padrão, mas podemos especificar a codificação com o parâmetro -Encoding.

$html | Out-File -FilePath "C:\Relatorios\processos.html" -Encoding utf8

Se você estiver usando PowerShell 7+, o padrão já é UTF-8 sem BOM, mas é sempre bom ser explícito. Outra alternativa é usar Set-Content, que também aceita o parâmetro -Encoding.

Para verificar se o arquivo foi criado corretamente, podemos abri-lo no navegador padrão com o cmdlet Start-Process:

Start-Process "C:\Relatorios\processos.html"

Além disso, podemos criar uma função que encapsula todo o processo, facilitando a reutilização em outras tarefas de automação. Vamos criar um script completo que coleta os dados, gera o HTML e exporta, tudo em um único bloco:

function New-ProcessReport {
    param(
        [string]$Path = "$PSScriptRoot\processos.html"
    )
    $processos = Get-Process |
        Sort-Object -Property WorkingSet -Descending |
        Select-Object -First 10 -Property Name, Id, CPU, @{Name='Memória (MB)'; Expression={[math]::Round($_.WorkingSet / 1MB, 2)}}
    $head = @'

'@
    $data = Get-Date -Format "dd/MM/yyyy HH:mm"
    $preContent = "

Relatório de Processos

Gerado em: $data

" $html = $processos | ConvertTo-Html -Head $head -PreContent $preContent -Title "Relatório de Processos" $html | Out-File -FilePath $Path -Encoding utf8 Write-Host "Relatório gerado em $Path" } New-ProcessReport

Essa função pode ser facilmente adaptada para outros tipos de relatórios, como serviços, eventos ou informações de hardware.

Boas práticas e observações finais

Ao criar relatórios HTML com PowerShell, considere as seguintes boas práticas: sempre valide os dados antes de gerar o relatório; use propriedades calculadas para formatar valores; mantenha o CSS em um arquivo separado se o relatório for reutilizado; e teste o relatório em diferentes navegadores. Além disso, é importante tratar erros, especialmente se os dados não estiverem disponíveis. Use blocos try/catch para capturar exceções e gerar um relatório de erro, se necessário.

Outra dica é usar o parâmetro -Fragment do ConvertTo-Html para gerar apenas o fragmento da tabela, que pode ser incorporado em uma página maior. Isso é útil se você estiver montando um painel com várias tabelas.

Por fim, lembre-se de que o PowerShell pode ser usado para agendar a geração de relatórios via Task Scheduler, garantindo que os relatórios sejam sempre atualizados.

Exercícios

  1. Crie um script que gere um relatório HTML com os 5 serviços que estão em execução, ordenados por nome. Inclua as propriedades: Nome, Status, StartType. Estilize com CSS básico.
  2. ✓ Resposta:
    $servicos = Get-Service | Where-Object Status -eq 'Running' | Sort-Object Name | Select-Object Name, Status, StartType
    $head = @'
    
    '@
    $preContent = "

    Serviços em Execução

    " $html = $servicos | ConvertTo-Html -Head $head -PreContent $preContent -Title "Relatório de Serviços" $html | Out-File -FilePath "servicos.html" -Encoding utf8
  3. Modifique o projeto principal para incluir uma coluna com o caminho do executável de cada processo. Dica: use a propriedade Path do objeto processo.
  4. ✓ Resposta:
    $processos = Get-Process |
        Sort-Object -Property WorkingSet -Descending |
        Select-Object -First 10 -Property Name, Id, CPU, Path, @{Name='Memória (MB)'; Expression={[math]::Round($_.WorkingSet / 1MB, 2)}}
    # ... restante do script igual
  5. Adicione um rodapé ao relatório com o texto "Gerado por [seu nome]" usando o parâmetro -PostContent.
  6. ✓ Resposta:
    $postContent = "
    Gerado por João Silva
    " $html = $processos | ConvertTo-Html -Head $head -PreContent $preContent -PostContent $postContent -Title "Relatório de Processos"
  7. Crie um relatório que liste os 10 arquivos maiores de uma pasta, incluindo nome, tamanho em MB e data de modificação. Use Get-ChildItem e Sort-Object.
  8. ✓ Resposta:
    $arquivos = Get-ChildItem -Path "C:\Windows\System32" -File |
        Sort-Object -Property Length -Descending |
        Select-Object -First 10 -Property Name, @{Name='Tamanho (MB)'; Expression={[math]::Round($_.Length / 1MB, 2)}}, LastWriteTime
    $head = @'
    
    '@
    $html = $arquivos | ConvertTo-Html -Head $head -Title "Maiores Arquivos"
    $html | Out-File -FilePath "arquivos.html" -Encoding utf8
  9. Automatize a geração do relatório de processos para que seja executado diariamente às 9h, usando o Agendador de Tarefas. Descreva os passos e forneça o comando PowerShell para registrar a tarefa.
  10. ✓ Resposta:
    $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\Scripts\New-ProcessReport.ps1"
    $trigger = New-ScheduledTaskTrigger -Daily -At 9am
    Register-ScheduledTask -TaskName "RelatorioProcessos" -Action $action -Trigger $trigger

Referências