Fala pessoal, tudo bem com vocês?

No post anterior eu mostrei como usar PowerShell para monitorar e automatizar serviços do Windows.

Agora eu trago uma versão melhorada e mais completa, voltada para quem precisa auditar logons e logoffs de usuários, seja em servidores ou estações de trabalho.


O que essa versão traz de novo

Com esse script você vai conseguir:

  • Coletar eventos de Logon (4624), Logoff (4634) e Logoff de usuário (4647).
  • Definir a quantidade de dias que deseja analisar.
  • Gerar relatórios em dois formatos:
    • CSV – perfeito para Excel ou Power BI.
    • HTML – visual limpo e pronto para abrir no navegador.
  • Obter informações importantes como:
    • Data do evento
    • Usuário
    • Tipo de logon
    • Máquina de origem

Tudo isso de forma automatizada, com mensagens claras durante a execução.


Requisitos

Antes de rodar, verifique:

  • PowerShell 5 ou superior (já vem no Windows 10/11 e Windows Server 2016+).
  • Executar como Administrador (o log de segurança exige permissão elevada).

Como usar

  1. Copie o script abaixo e salve como, por exemplo: C:\\Scripts\\Relatorio-LogonLogoff.ps1
  2. Abra o PowerShell como Administrador.
  3. Execute: .\\Relatorio-LogonLogoff.ps1
  4. Informe o número de dias de eventos que deseja coletar.
  5. O script cria a pasta: C:\\Temp\\LogonLogoff E salva lá os relatórios:
    • Relatorio-Logonlogoff.csv
    • Relatorio-Logonlogoff.html

Script

Write-Host "Iniciando coleta de eventos de Logon/Logoff..." -ForegroundColor Cyan

try {
    [int]$Dias = Read-Host "Quantos dias de eventos você deseja coletar?"
}
catch {
    Write-Host "Entrada inválida. Por favor, insira um número inteiro (ex: 10)." -ForegroundColor Red
    return
}

$OutputFolder = "C:\\Temp\\LogonLogoff"
$OutputCsv = "$OutputFolder\\Relatorio-Logonlogoff.csv"
$OutputHtml = "$OutputFolder\\Relatorio-Logonlogoff.html"

$ReportDate = Get-Date -Format "dd/MM/yyyy HH:mm:ss"
$ComputerName = $env:COMPUTERNAME
$ReportCreator = $env:USERNAME

Write-Host "Verificando/Criando o diretório de saída: $OutputFolder" -ForegroundColor Blue
if (-not (Test-Path $OutputFolder)) {
    try {
        New-Item -Path $OutputFolder -ItemType Directory -Force | Out-Null
        Write-Host "Diretório '$OutputFolder' criado com sucesso!" -ForegroundColor Green
    }
    catch {
        Write-Host "Erro ao criar o diretório. Por favor, verifique suas permissões." -ForegroundColor Red
        return
    }
}

Write-Host "Buscando eventos dos últimos '$Dias' dias..." -ForegroundColor Blue
Write-Progress -Activity "Coletando eventos..." -Status "Isso pode levar alguns minutos..." -PercentComplete 10

try {
    $Events = Get-WinEvent -FilterHashtable @{
        LogName   = 'Security'
        Id        = 4624, 4634, 4647
        StartTime = (Get-Date).AddDays(-$Dias)
    } | Select-Object @{Name='Data do Evento'; Expression={$_.TimeCreated}},
        Id,
        @{Name='Usuário'; Expression={$_.Properties[5].Value}},
        @{Name='Tipo de Logon'; Expression={
            switch ($_.Properties[8].Value) {
                2 { "Interativo (Local)" }
                3 { "Rede" }
                4 { "Batch" }
                5 { "Serviço" }
                7 { "Desbloquear (Tela)" }
                10 { "RemoteInteractive (RDP/Terminal)" }
                default { "Outros" }
            }
        }},
        @{Name='Máquina de Origem'; Expression={$_.Properties[11].Value}}

    Write-Progress -Activity "Coletando eventos..." -Status "Coleta concluída. Salvando relatórios..." -PercentComplete 50

    $Events | Export-Csv -Path $OutputCsv -NoTypeInformation -Delimiter ';'
    Write-Host "Relatório CSV salvo em: $OutputCsv" -ForegroundColor Green

    $HtmlHeader = @"
<head>
    <title>Relatório de Logon/Logoff dos últimos $Dias dias</title>
    <style>
        body { font-family: Arial, sans-serif; background-color: #f4f4f4; color: #333; margin: 20px; }
        h1 { color: #0056b3; text-align: center; }
        .header-info { text-align: center; margin-bottom: 20px; }
        .header-info p { margin: 5px 0; font-size: 14px; }
        table { width: 100%; border-collapse: collapse; margin-top: 20px; }
        th, td { padding: 12px 15px; text-align: left; border-bottom: 1px solid #ddd; }
        th { background-color: #007bff; color: white; }
        tr:nth-child(even) { background-color: #f9f9f9; }
        tr:hover { background-color: #f1f1f1; }
    </style>
</head>
"@
    $HtmlBody = @"
<body>
    <div class="header-info">
        <h1>Relatório de Logon/Logoff dos últimos $Dias dias</h1>
        <p><strong>Relatório Gerado em:</strong> $ReportDate</p>
        <p><strong>Computador:</strong> $ComputerName</p>
        <p><strong>Criado por:</strong> $ReportCreator</p>
    </div>
"@

    $EventsHtmlTable = $Events | ConvertTo-Html -As Table -Fragment
    $HtmlContent = "<html>" + $HtmlHeader + $HtmlBody + $EventsHtmlTable + "</body></html>"
    $HtmlContent | Out-File -FilePath $OutputHtml -Encoding UTF8

    Write-Host "Relatório HTML salvo em: $OutputHtml" -ForegroundColor Green
    Write-Progress -Activity "Coletando eventos..." -Status "Relatórios prontos!" -PercentComplete 100
    Start-Sleep -Seconds 2
}
catch {
    Write-Host "Ocorreu um erro ao coletar os eventos. Verifique se o script está rodando como Administrador e se você tem eventos de segurança disponíveis." -ForegroundColor Red
}


Resultado

O relatório em HTML final traz uma tabela bem organizada com todos os eventos coletados, pronta para:

  • consulta rápida,
  • envio em relatórios internos,
  • ou até integração em um processo de auditoria.

Conclusão

Esse script deixa o processo de auditoria de logon/logoff muito mais simples e visual.

Se você já faz esse tipo de análise no dia a dia, pode usar essa versão como base e adaptá-la conforme a sua necessidade.

E aí, o que vocês acharam dessa versão melhorada?

Deixem nos comentários como vocês fazem o monitoramento de logon/logoff no ambiente de vocês!

Rolar para cima