Como criar um relatório de integridade de ficheiros em PowerShell
Este tutorial mostra como criar um relatório de integridade de ficheiros em PowerShell para verificar alterações em ficheiros críticos. A solução gera e guarda hashes (SHA256) de ficheiros, compara versões posteriores e destaca ficheiros adicionados, removidos ou modificados — útil para auditorias, deteção de alterações não autorizadas e cópias de segurança verificadas.
Pré-requisitos
- Windows com PowerShell 5.1 ou PowerShell 7+
- Permissões de leitura para a pasta a verificar
- Uma pasta de relatório onde guardar o ficheiro de referência (JSON ou CSV)
Passo 1: Conceito e estrutura do relatório
É importante perceber o que vamos gravar: para cada ficheiro guardamos o caminho relativo, o tamanho, a última data de modificação e o hash SHA256. O formato JSON é simples de ler e fácil de comparar. O ficheiro de referência será chamado file-integrity.json.
Passo 2: Script para gerar o relatório inicial
Este script cria o relatório inicial com todos os ficheiros da pasta alvo. Execute-o a partir da pasta pai ou forneça um caminho completo para $RootPath.
$RootPath = 'C:\PastaASeguir' # Alterar para a pasta a verificar
$ReportFile = 'C:\Relatorios\file-integrity.json' # Onde guardar o relatório
Get-ChildItem -Path $RootPath -Recurse -File | ForEach-Object {
$relative = $_.FullName.Substring($RootPath.Length).TrimStart('\')
$hash = Get-FileHash -Path $_.FullName -Algorithm SHA256
[PSCustomObject]@{
Path = $relative
Size = $_.Length
LastWriteTime = $_.LastWriteTimeUtc
Hash = $hash.Hash
}
} | ConvertTo-Json -Depth 4 | Out-File -FilePath $ReportFile -Encoding UTF8
Write-Output "Relatório inicial gerado em: $ReportFile"
Passo 3: Script para comparar o estado atual com o relatório
Este script carrega o relatório anterior, analisa o estado atual da pasta e identifica ficheiros Added, Removed e Modified. Guarda também um novo relatório com timestamp para histórico.
$RootPath = 'C:\PastaASeguir'
$ReportFile = 'C:\Relatorios\file-integrity.json'
$NowReport = "C:\Relatorios\file-integrity-$(Get-Date -Format 'yyyyMMdd-HHmmss').json"
# Carregar relatório anterior
if (-Not (Test-Path $ReportFile)) { throw "Relatório anterior não encontrado: $ReportFile" }
$old = Get-Content $ReportFile -Raw | ConvertFrom-Json
$oldIndex = @{ }
foreach ($item in $old) { $oldIndex[$item.Path] = $item }
# Criar relatório atual em memória
$current = @()
Get-ChildItem -Path $RootPath -Recurse -File | ForEach-Object {
$relative = $_.FullName.Substring($RootPath.Length).TrimStart('\')
$hash = Get-FileHash -Path $_.FullName -Algorithm SHA256
$current += [PSCustomObject]@{
Path = $relative
Size = $_.Length
LastWriteTime = $_.LastWriteTimeUtc
Hash = $hash.Hash
}
}
# Index current
$currentIndex = @{ }
foreach ($item in $current) { $currentIndex[$item.Path] = $item }
# Detetar Added, Removed, Modified
$added = @()
$removed = @()
$modified = @()
foreach ($path in $currentIndex.Keys) {
if (-Not $oldIndex.ContainsKey($path)) { $added += $currentIndex[$path] }
else {
$oldItem = $oldIndex[$path]
$curItem = $currentIndex[$path]
if ($oldItem.Hash -ne $curItem.Hash -or $oldItem.Size -ne $curItem.Size) {
$modified += [PSCustomObject]@{
Path = $path
OldHash = $oldItem.Hash
NewHash = $curItem.Hash
OldSize = $oldItem.Size
NewSize = $curItem.Size
}
}
}
}
foreach ($path in $oldIndex.Keys) {
if (-Not $currentIndex.ContainsKey($path)) { $removed += $oldIndex[$path] }
}
# Guardar relatório atual para histórico
$current | ConvertTo-Json -Depth 4 | Out-File -FilePath $NowReport -Encoding UTF8
# Output resumido
$summary = [PSCustomObject]@{
Timestamp = (Get-Date).ToString('o')
Added = $added.Count
Removed = $removed.Count
Modified = $modified.Count
NewReport = $NowReport
}
$summary | ConvertTo-Json -Depth 3
# Também podemos guardar um log simples
$logFile = 'C:\Relatorios\file-integrity-log.txt'
Add-Content -Path $logFile -Value ("$((Get-Date).ToString('s')) - Added:$($added.Count) Removed:$($removed.Count) Modified:$($modified.Count)")
# Opcional: sobrescrever o relatório de referência para próxima comparação
$current | ConvertTo-Json -Depth 4 | Out-File -FilePath $ReportFile -Encoding UTF8
Passo 4: Agendar ou automatizar a verificação
Para executar automaticamente, use o Task Scheduler. Crie uma tarefa que execute PowerShell com o caminho do script e parâmetros se necessário. Configure para correr com permissões adequadas e com um trigger (ex.: diário ou a cada hora).
Verificar o resultado
Verifique os ficheiros JSON e o log: o resumo em JSON mostra Added, Removed e Modified. Abra o ficheiro file-integrity-log.txt para um histórico rápido. Em caso de Modified, compare OldHash vs NewHash para confirmar alterações. Erros comuns: paths com permissões insuficientes ou exceções em ficheiros bloqueados — corrija permissões ou execute com uma conta que tenha acesso.
Conclusão
Tem agora uma solução simples para gerar e comparar relatórios de integridade de ficheiros com PowerShell; próximos passos incluem notificação por email quando houver alterações, excluir tipos de ficheiro específicos ou integrar com SIEM. Dica: teste primeiro numa pasta pequena para validar hashes e permissões antes de aplicar em produção.