Projeto: inventário de sistema
LidoNesta aula, vamos construir um projeto completo de inventário de sistema usando PowerShell, desde a coleta de informações do hardware e software até a geração de um relatório formatado e exportado. Você aprenderá a usar cmdlets como Get-ComputerInfo, a formatar saídas com Format-Table e ConvertTo-HTML, e a agendar a execução automática com o Agendador de Tarefas.
Nesta aula, vamos colocar em prática tudo o que aprendemos até agora construindo um projeto completo: um inventário de sistema. O objetivo é criar um script que colete informações relevantes sobre o computador (hardware, sistema operacional, software instalado), formate essas informações de maneira legível e gere um relatório em formato HTML ou CSV. Além disso, vamos configurar o script para ser executado automaticamente em intervalos regulares, garantindo que o inventário esteja sempre atualizado.
Este projeto é um exemplo clássico de automação com PowerShell: você pode usá-lo em ambientes corporativos para manter um registro dos equipamentos, auxiliar no suporte técnico ou simplesmente para ter um diagnóstico rápido do seu próprio sistema. Vamos dividir o projeto em etapas: coleta, formatação, exportação e agendamento. Ao final, você terá um script robusto e reutilizável.
Coletando informações
O primeiro passo é reunir as informações do sistema. O PowerShell oferece uma variedade de cmdlets para isso. O cmdlet Get-ComputerInfo é um dos mais completos, pois retorna um objeto com dezenas de propriedades, como fabricante, modelo, versão do sistema operacional, memória total, entre outras. No entanto, ele pode ser lento em algumas máquinas porque consulta várias fontes. Para informações mais específicas, podemos usar cmdlets como Get-CimInstance (ou o antigo Get-WmiObject) para acessar classes WMI/CIM, como Win32_Processor, Win32_BIOS, Win32_OperatingSystem e Win32_LogicalDisk.
Além disso, é comum querer listar o software instalado. Podemos obter isso consultando o registro do Windows ou usando o cmdlet Get-Package (disponível no PackageManagement). Vamos criar uma função que coleta as principais informações e as armazena em um objeto personalizado. Isso facilita a formatação e exportação posterior.
Aqui está um exemplo de script para coleta de informações básicas:
function Get-SystemInventory {
$computerInfo = Get-ComputerInfo
$os = Get-CimInstance -ClassName Win32_OperatingSystem
$cpu = Get-CimInstance -ClassName Win32_Processor
$disk = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3"
$bios = Get-CimInstance -ClassName Win32_BIOS
# Criando um objeto personalizado com as informações principais
$inventory = [PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
Manufacturer = $computerInfo.Manufacturer
Model = $computerInfo.Model
SerialNumber = $bios.SerialNumber
OSName = $os.Caption
OSVersion = $os.Version
LastBoot = $os.LastBootUpTime
CPUName = $cpu.Name
CPUCores = $cpu.NumberOfCores
TotalRAM = [math]::Round($computerInfo.TotalPhysicalMemory / 1GB, 2)
FreeDiskC = [math]::Round(($disk | Where-Object {$_.DeviceID -eq "C:"}).FreeSpace / 1GB, 2)
TotalDiskC = [math]::Round(($disk | Where-Object {$_.DeviceID -eq "C:"}).Size / 1GB, 2)
}
return $inventory
}
# Executando a função
Get-SystemInventoryNo script acima, usamos Get-ComputerInfo para dados gerais, mas também consultamos classes CIM específicas para garantir informações como número de série e espaço em disco. Observe que convertemos bytes para GB para facilitar a leitura. Você pode expandir essa função para incluir outros detalhes, como endereço IP, placa de vídeo ou lista de softwares instalados.
Formatando
Depois de coletar os dados, é hora de formatá-los para que fiquem apresentáveis. O PowerShell oferece vários cmdlets para isso: Format-Table, Format-List e ConvertTo-HTML. Para um relatório visual, o HTML é uma ótima opção, pois pode ser aberto em qualquer navegador e estilizado com CSS. Para dados tabulares, CSV é útil para importar em planilhas.
Vamos criar uma versão formatada do inventário. Primeiro, podemos exibir na tela com Format-List para uma visão detalhada, ou Format-Table para uma tabela compacta. Para o relatório final, usaremos ConvertTo-HTML para gerar uma página HTML com uma tabela.
Exemplo de formatação e geração de HTML:
# Coleta o inventário
$inventory = Get-SystemInventory
# Exibe na tela em formato de lista
$inventory | Format-List
# Converte para HTML com um pouco de estilo
$html = $inventory | ConvertTo-HTML -Property ComputerName, Manufacturer, Model, SerialNumber, OSName, OSVersion, LastBoot, CPUName, CPUCores, TotalRAM, FreeDiskC, TotalDiskC -Title "Inventário do Sistema" -Head ""
# Salva em arquivo
$html | Out-File -FilePath "$env:USERPROFILE\Desktop\inventario.html" -Encoding utf8
Write-Host "Relatório gerado em $env:USERPROFILE\Desktop\inventario.html" -ForegroundColor GreenO parâmetro -Head permite inserir CSS para melhorar a aparência. Você pode personalizar o HTML conforme necessário. Se preferir CSV, basta usar Export-Csv:
$inventory | Export-Csv -Path "$env:USERPROFILE\Desktop\inventario.csv" -NoTypeInformationLembre-se de que ConvertTo-HTML gera uma tabela simples; para relatórios mais elaborados, você pode construir o HTML manualmente ou usar fragmentos. Mas para este projeto, essa abordagem é suficiente.
Exportando relatório
A exportação é a etapa em que salvamos o relatório em um arquivo. Vimos acima como gerar HTML e CSV. É importante decidir onde salvar o arquivo. Uma boa prática é criar uma pasta específica para relatórios, por exemplo, C:\Inventario. Vamos melhorar o script para verificar se a pasta existe e criá-la se necessário. Além disso, podemos incluir a data no nome do arquivo para manter um histórico.
Vamos criar uma função que exporta o inventário em ambos os formatos (HTML e CSV) e também retorna o caminho dos arquivos gerados.
function Export-SystemInventory {
param(
[string]$Path = "C:\Inventario"
)
# Cria a pasta se não existir
if (-not (Test-Path $Path)) {
New-Item -ItemType Directory -Path $Path -Force | Out-Null
}
$date = Get-Date -Format "yyyyMMdd_HHmm"
$inventory = Get-SystemInventory
# Exporta para HTML
$html = $inventory | ConvertTo-HTML -Property ComputerName, Manufacturer, Model, SerialNumber, OSName, OSVersion, LastBoot, CPUName, CPUCores, TotalRAM, FreeDiskC, TotalDiskC -Title "Inventário do Sistema" -Head ""
$htmlPath = Join-Path $Path "inventario_$date.html"
$html | Out-File -FilePath $htmlPath -Encoding utf8
# Exporta para CSV
$csvPath = Join-Path $Path "inventario_$date.csv"
$inventory | Export-Csv -Path $csvPath -NoTypeInformation
Write-Host "Relatórios gerados:" -ForegroundColor Green
Write-Host "HTML: $htmlPath"
Write-Host "CSV: $csvPath"
}
# Exemplo de uso
Export-SystemInventory -Path "C:\Inventario"Neste script, usamos Get-Date para incluir um carimbo de data/hora no nome do arquivo, evitando sobrescritas. A função também retorna os caminhos para que você possa usá-los em outras automações, como enviar por e-mail.
Agendamento
Para que o inventário seja gerado automaticamente, podemos usar o Agendador de Tarefas do Windows. O PowerShell pode interagir com ele através do módulo ScheduledTasks. Vamos criar uma tarefa que executa nosso script diariamente em um horário específico.
Primeiro, precisamos salvar nosso script de inventário em um arquivo .ps1. Vamos supor que ele está em C:\Scripts\Inventario.ps1. A função Export-SystemInventory deve ser chamada no final do script. Depois, criamos a tarefa agendada.
Exemplo de agendamento:
# Define o caminho do script
$scriptPath = "C:\Scripts\Inventario.ps1"
# Cria a ação que executa o PowerShell com o script
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File `"$scriptPath`""
# Define o gatilho: diariamente às 7h
$trigger = New-ScheduledTaskTrigger -Daily -At "07:00"
# Define o usuário que executará a tarefa (pode ser SYSTEM)
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
# Registra a tarefa
Register-ScheduledTask -TaskName "InventarioSistema" -Action $action -Trigger $trigger -Principal $principal -Description "Gera inventário do sistema diariamente"Se preferir agendar via interface gráfica, você pode usar o schtasks.exe ou o agendador manualmente. O comando acima cria uma tarefa que roda como SYSTEM, sem necessidade de senha. Para testar, você pode executar a tarefa manualmente:
Start-ScheduledTask -TaskName "InventarioSistema"Lembre-se de que, se o script for executado como SYSTEM, ele precisará de permissões adequadas para acessar pastas como C:\Inventario. Verifique se o diretório existe e tem permissões de escrita para o usuário SYSTEM.
Boas práticas e observações finais
Ao desenvolver scripts de inventário, considere as seguintes boas práticas:
- Modularize: separe a coleta, formatação e exportação em funções para facilitar a manutenção.
- Trate erros: use
try/catchpara capturar falhas ao acessar informações do sistema. - Documente: inclua comentários explicando o propósito de cada bloco.
- Segurança: ao agendar, use uma conta com privilégios mínimos necessários.
- Teste: execute o script manualmente antes de agendar para garantir que tudo funciona.
Este projeto pode ser expandido para incluir informações de rede, lista de serviços, eventos do sistema, e até mesmo gerar relatórios em PDF. O PowerShell oferece infinitas possibilidades de automação.
Referências
- Get-ComputerInfo (Microsoft Learn)
- Get-CimInstance (Microsoft Learn)
- ConvertTo-HTML (Microsoft Learn)
- Export-Csv (Microsoft Learn)
- Register-ScheduledTask (Microsoft Learn)
- Criando caixas de entrada personalizadas (Microsoft Learn)
- PowerShell Gallery
Exercícios
- Exercício 1: Modifique a função
Get-SystemInventorypara incluir a quantidade de memória disponível (não apenas total) e o espaço livre em todos os discos, não apenas C:. - Exercício 2: Crie uma função que exporte o inventário em formato JSON, além de HTML e CSV.
- Exercício 3: Agende o script para ser executado toda segunda-feira às 9h, usando o cmdlet Register-ScheduledTask.
- Exercício 4: Escreva um código que envie um e-mail com o relatório em anexo, usando Send-MailMessage (ou Send-MailKitMessage se disponível).
- Exercício 5: Implemente tratamento de erro na função Get-SystemInventory para que, se Get-ComputerInfo falhar, o script continue usando Get-CimInstance.
function Get-SystemInventory {
$computerInfo = Get-ComputerInfo
$os = Get-CimInstance -ClassName Win32_OperatingSystem
$cpu = Get-CimInstance -ClassName Win32_Processor
$disks = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3"
$bios = Get-CimInstance -ClassName Win32_BIOS
$diskInfo = foreach ($disk in $disks) {
[PSCustomObject]@{
Drive = $disk.DeviceID
FreeSpaceGB = [math]::Round($disk.FreeSpace / 1GB, 2)
TotalSizeGB = [math]::Round($disk.Size / 1GB, 2)
}
}
$inventory = [PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
Manufacturer = $computerInfo.Manufacturer
Model = $computerInfo.Model
SerialNumber = $bios.SerialNumber
OSName = $os.Caption
OSVersion = $os.Version
LastBoot = $os.LastBootUpTime
CPUName = $cpu.Name
CPUCores = $cpu.NumberOfCores
TotalRAM = [math]::Round($computerInfo.TotalPhysicalMemory / 1GB, 2)
FreeRAM = [math]::Round($os.FreePhysicalMemory / 1MB, 2)
Disks = $diskInfo
}
return $inventory
}function Export-SystemInventoryJson {
param([string]$Path = "C:\Inventario")
if (-not (Test-Path $Path)) { New-Item -ItemType Directory -Path $Path -Force | Out-Null }
$inventory = Get-SystemInventory
$jsonPath = Join-Path $Path "inventario_$(Get-Date -Format 'yyyyMMdd_HHmm').json"
$inventory | ConvertTo-Json -Depth 3 | Out-File -FilePath $jsonPath -Encoding utf8
Write-Host "JSON exportado para $jsonPath"
}$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File `"C:\Scripts\Inventario.ps1`""
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At "09:00"
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "InventarioSemanal" -Action $action -Trigger $trigger -Principal $principal -Description "Inventário semanal"$smtpServer = "smtp.seudominio.com"
$from = "inventario@seudominio.com"
$to = "admin@seudominio.com"
$subject = "Inventário do Sistema"
$body = "Segue o relatório de inventário."
$attachment = "C:\Inventario\inventario_$(Get-Date -Format 'yyyyMMdd_HHmm').html"
Send-MailMessage -SmtpServer $smtpServer -From $from -To $to -Subject $subject -Body $body -Attachments $attachmentfunction Get-SystemInventory {
try {
$computerInfo = Get-ComputerInfo -ErrorAction Stop
} catch {
Write-Warning "Get-ComputerInfo falhou, usando CIM"
$computerInfo = Get-CimInstance -ClassName Win32_ComputerSystem
}
# ... resto do código
}