(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como monitorizar alterações de permissões NTFS em PowerShell: passo a passo

João Barros 18 de August de 2026 4 min de leitura

Este tutorial mostra como monitorizar alterações de permissões NTFS em PowerShell para detetar quando as ACLs (Access Control Lists) de ficheiros ou pastas são alteradas. É útil para auditoria, segurança e para manter o controlo sobre quem tem acesso a dados sensíveis.

Pré-requisitos

  • Windows 10/11 ou Windows Server com PowerShell 5.1 ou PowerShell 7+
  • Permissões de leitura nas pastas a monitorizar
  • Preferível executar o PowerShell com privilégios elevados para aceder a todas as ACLs
  • Editor de texto (ex.: Visual Studio Code) para guardar o script

Passo 1: Porque monitorizar ACLs e a abordagem

Alterações a permissões NTFS nem sempre criam um evento claro no sistema. A abordagem aqui é ler periodicamente as ACLs de uma pasta/ficheiro, gerar um hash representativo e comparar com o snapshot anterior. Quando o hash muda, regista-se a diferença e envia-se uma notificação simples.

Passo 2: Função para obter um 'fingerprint' da ACL

Vamos criar uma função que lê a ACL de uma pasta e cria um fingerprint consistente. Isto permite comparar versões de forma rápida.

function Get-AclFingerprint {
    param(
        [Parameter(Mandatory)] [string] $Path
    )
    # Obtém a ACL e cria uma string ordenada para hashing
    $acl = Get-Acl -Path $Path
    $entries = $acl.Access | ForEach-Object {
        "{0}|{1}|{2}|{3}|{4}" -f $_.IdentityReference, $_.FileSystemRights, $_.AccessControlType, $_.InheritanceFlags, $_.PropagationFlags
    }
    $entries = $entries | Sort-Object
    $joined = $entries -join ";"
    # MD5 é suficiente para fingerprint (não para segurança criptográfica)
    $md5 = [System.Security.Cryptography.MD5]::Create()
    $bytes = [System.Text.Encoding]::UTF8.GetBytes($joined)
    $hash = $md5.ComputeHash($bytes)
    return ([System.BitConverter]::ToString($hash)).Replace("-","")
}

Passo 3: Capturar snapshot inicial e guardar em ficheiro

Guarde o fingerprint inicial num ficheiro JSON para comparações futuras. Pode monitorizar várias pastas guardando um objecto por caminho.

$paths = @('C:\Dados\Projeto', 'C:\Logs')
$snapshot = @{}
foreach ($p in $paths) {
    if (Test-Path $p) {
        $snapshot[$p] = Get-AclFingerprint -Path $p
    }
}
$snapshot | ConvertTo-Json | Out-File -FilePath 'C:\MonitorACL\acl_snapshot.json' -Encoding UTF8

Passo 4: Script de monitorização e deteção de mudanças

Script que carrega o snapshot, recalcula fingerprints e, ao detectar mudança, escreve para um log e grava o novo snapshot. Também mostra como obter a diferença nas entradas ACL para contextualizar a alteração.

# Requer a função Get-AclFingerprint definida acima
$snapshotPath = 'C:\MonitorACL\acl_snapshot.json'
$logPath = 'C:\MonitorACL\acl_changes.log'
$paths = @('C:\Dados\Projeto', 'C:\Logs')

# Carrega snapshot existente
if (Test-Path $snapshotPath) {
    $oldSnapshot = Get-Content $snapshotPath -Raw | ConvertFrom-Json | ConvertTo-Hashtable
} else {
    $oldSnapshot = @{}
}

foreach ($p in $paths) {
    if (-not (Test-Path $p)) { continue }
    $newHash = Get-AclFingerprint -Path $p
    $oldHash = $oldSnapshot[$p]
    if ($oldHash -ne $null -and $newHash -ne $oldHash) {
        $time = (Get-Date).ToString('s')
        $msg = "[$time] ACL altered for $p (old:$oldHash new:$newHash)"
        $msg | Out-File -FilePath $logPath -Append -Encoding UTF8

        # Opcional: obter e registar entradas ACL actuais para análise
        $acl = Get-Acl -Path $p
        $entries = $acl.Access | ForEach-Object { "{0} {1} {2}" -f $_.IdentityReference, $_.FileSystemRights, $_.AccessControlType }
        ($time + ' - Entries:') | Out-File -FilePath $logPath -Append -Encoding UTF8
        $entries | Out-File -FilePath $logPath -Append -Encoding UTF8
    }
    # Actualiza snapshot em memória
    $oldSnapshot[$p] = $newHash
}

# Grava snapshot actualizado
$oldSnapshot | ConvertTo-Json | Out-File -FilePath $snapshotPath -Encoding UTF8

Passo 5: Agendar execução periódica (exemplo rápido)

Para monitorização contínua, pode executar o script num loop com atraso ou usar o Task Scheduler. Exemplo de loop simples que corre a cada 5 minutos (útil para testes).

while ($true) {
    & 'C:\MonitorACL\Check-AclChanges.ps1'
    Start-Sleep -Seconds 300
}

Verificar o resultado

Abra o ficheiro de log definido (ex.: C:\MonitorACL\acl_changes.log) para ver entradas com timestamps quando ocorreram alterações. Verifique também acl_snapshot.json para confirmar que os hashes foram actualizados. Se não surgir nenhum registo apesar de alterações, confirme permissões, caminhos e se o script tem acesso a Get-Acl para esses itens.

Conclusão

Com este método simples consegue monitorizar alterações de permissões NTFS usando PowerShell, registar eventos e guardar snapshots para auditoria. Próximos passos: integrar com envio de e-mail ou Teams quando ocorrer uma alteração, e usar Event Forwarding para centralizar logs. Dica: teste primeiro em pastas não críticas para validar falsos positivos e ajustar a frequência de verificação.