Logs de eventos
Esta aula aborda como trabalhar com logs de eventos no Windows usando PowerShell. Você aprenderá a diferença entre Get-EventLog e Get-WinEvent, técnicas de filtragem eficientes, métodos de análise de logs e casos de uso práticos para administração e segurança.
Os logs de eventos do Windows são uma fonte rica de informações sobre o sistema, aplicativos e segurança. Dominar a leitura e análise desses logs é essencial para qualquer profissional de TI que utiliza PowerShell. Nesta aula, você aprenderá a utilizar os cmdlets Get-EventLog e Get-WinEvent, entenderá as diferenças entre eles, e verá como filtrar, analisar e aplicar esse conhecimento em cenários reais.
Enquanto Get-EventLog é um cmdlet mais antigo e simples, Get-WinEvent é a ferramenta moderna e recomendada, oferecendo maior flexibilidade e desempenho. Vamos explorar ambos, mas com ênfase no Get-WinEvent, pois é o futuro da administração de logs.
Get-EventLog e Get-WinEvent
O cmdlet Get-EventLog foi introduzido no Windows PowerShell 1.0 e permite acessar logs de eventos clássicos, como Application, System e Security. Ele é simples de usar, mas limitado: não suporta consultas complexas e não acessa logs de eventos do Windows PowerShell ou logs de aplicativos modernos.
Por outro lado, Get-WinEvent foi introduzido no PowerShell 3.0 e é o cmdlet recomendado. Ele acessa todos os logs de eventos, incluindo os novos logs do Windows, e oferece suporte a consultas XPath, filtros avançados e melhor desempenho. Além disso, Get-WinEvent pode consultar logs em computadores remotos de forma mais eficiente.
Vamos ver exemplos de uso de ambos:
# Usando Get-EventLog (clássico)
Get-EventLog -LogName System -Newest 5
# Usando Get-WinEvent (moderno)
Get-WinEvent -LogName System -MaxEvents 5
Ambos retornam os cinco eventos mais recentes do log System. No entanto, Get-WinEvent retorna objetos do tipo System.Diagnostics.Eventing.Reader.EventLogRecord, que são mais ricos e consistentes. O Get-EventLog retorna objetos System.Diagnostics.EventLogEntry, que são mais simples.
Para listar todos os logs disponíveis, use:
Get-WinEvent -ListLog * | Select-Object LogName, RecordCount, IsEnabled
Isso é útil para descobrir logs personalizados ou de aplicativos.
Filtragem
A filtragem é uma das operações mais importantes ao trabalhar com logs de eventos. Você pode filtrar por data, nível de severidade, ID do evento, origem, usuário, entre outros. Com Get-WinEvent, você pode usar o parâmetro -FilterHashtable para criar filtros eficientes.
Por exemplo, para buscar eventos de erro no log System dos últimos 7 dias:
$startDate = (Get-Date).AddDays(-7)
Get-WinEvent -FilterHashtable @{ LogName='System'; Level=2; StartTime=$startDate }
O parâmetro -FilterXPath permite consultas mais avançadas, como:
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4624 or EventID=4625) and TimeCreated[timediff(@SystemTime) <= 86400000]]]"
Esse exemplo busca eventos de logon bem-sucedido (4624) e falha (4625) nas últimas 24 horas.
Você também pode filtrar usando o pipeline e cmdlets como Where-Object, mas isso é menos eficiente para grandes volumes. Prefira sempre os filtros nativos.
Para filtrar por múltiplos critérios no -FilterHashtable, você pode usar chaves como Id, ProviderName, StartTime, EndTime, Level etc. Exemplo:
Get-WinEvent -FilterHashtable @{ LogName='Application'; Level=3; ProviderName='.NET Runtime' }
Isso retorna eventos de aviso do provedor .NET Runtime no log Application.
Análise
Depois de obter os eventos, você pode analisá-los de várias maneiras. Uma abordagem comum é agrupar eventos por propriedade, como ID ou nível, para identificar padrões. O cmdlet Group-Object é útil para isso.
$events = Get-WinEvent -LogName System -MaxEvents 1000
$events | Group-Object Id | Sort-Object Count -Descending | Select-Object Count, Name
Isso mostra os IDs de eventos mais frequentes no log System.
Você também pode analisar a distribuição de eventos ao longo do tempo, usando Group-Object com uma data formatada:
$events | Group-Object { $_.TimeCreated.ToString("yyyy-MM-dd") } | Select-Object Name, Count
Para extrair mensagens detalhadas, você pode acessar a propriedade Message:
Get-WinEvent -LogName System -MaxEvents 1 | Select-Object -ExpandProperty Message
Ou formatar a saída como tabela ou lista:
Get-WinEvent -LogName System -MaxEvents 5 | Format-Table TimeCreated, Id, LevelDisplayName, ProviderName
Para exportar eventos para análise em outra ferramenta, você pode usar Export-Csv ou ConvertTo-Json:
Get-WinEvent -LogName Security -MaxEvents 100 | Export-Csv -Path "security_events.csv" -NoTypeInformation
Isso permite abrir os dados em Excel ou outras ferramentas de BI.
Casos de uso
Os logs de eventos são fundamentais para várias tarefas administrativas e de segurança. Aqui estão alguns casos práticos:
- Monitoramento de segurança: Detectar tentativas de logon falhas (Event ID 4625) ou contas bloqueadas (Event ID 4740).
- Troubleshooting de aplicativos: Identificar erros recorrentes de um aplicativo específico no log Application.
- Auditoria de alterações: Rastrear mudanças em políticas de segurança (Event ID 4719) ou instalação de software (Event ID 11707).
- Monitoramento de desempenho: Verificar eventos de erro de disco (Event ID 7 ou 51) no log System.
- Automação de relatórios: Gerar relatórios diários de eventos críticos.
Exemplo de script para monitorar falhas de logon:
$startDate = (Get-Date).AddHours(-24)
$failedLogons = Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4625; StartTime=$startDate }
if ($failedLogons.Count -gt 0) {
Write-Host "Atenção: $($failedLogons.Count) tentativas de logon falhas nas últimas 24 horas."
$failedLogons | Select-Object TimeCreated, Message
} else {
Write-Host "Nenhuma tentativa de logon falha nas últimas 24 horas."
}
Outro caso é limpar logs antigos, embora seja necessário cuidado:
# Limpar eventos com mais de 30 dias do log Application
$cutoff = (Get-Date).AddDays(-30)
Get-WinEvent -LogName Application | Where-Object { $_.TimeCreated -lt $cutoff } | Remove-EventLog -LogName Application
Note que Remove-EventLog remove o log inteiro, não eventos individuais. Para limpar eventos, você precisaria usar a API do Windows, mas isso é avançado e raramente necessário.
Boas práticas
- Sempre use
Get-WinEventem vez deGet-EventLogpara novos scripts. - Utilize filtros nativos (
-FilterHashtableou-FilterXPath) para consultas em grandes volumes de eventos. - Evite usar
Where-Objectpara filtrar eventos em logs grandes, pois é mais lento. - Limite a quantidade de eventos retornados com
-MaxEventspara evitar sobrecarga. - Exporte eventos para análise externa quando precisar de relatórios complexos.
- Considere a segurança: o log Security pode exigir privilégios elevados para leitura.
Referências
- Documentação oficial do Get-WinEvent
- Documentação oficial do Get-EventLog
- Consuming Events (Windows Event Log)
- Visão geral de auditoria de segurança do Windows
- Estrutura do log de eventos (Windows)
- Trabalhando com logs de eventos no PowerShell
Exercícios
- Exercício 1: Liste os 10 eventos mais recentes do log System usando
Get-WinEvente exiba apenas as propriedades TimeCreated, Id e ProviderName. - Exercício 2: Filtrar eventos de erro (Level=2) no log Application das últimas 24 horas usando
-FilterHashtable. - Exercício 3: Agrupe os eventos do log System (últimos 500) por ID e mostre os 5 IDs mais frequentes.
- Exercício 4: Exporte os eventos de segurança (Security) das últimas 24 horas para um arquivo CSV chamado "security_24h.csv".
- Exercício 5: Use
Get-WinEventcom-FilterXPathpara buscar eventos com ID 4624 ou 4625 no log Security das últimas 7 dias.
Get-WinEvent -LogName System -MaxEvents 10 | Select-Object TimeCreated, Id, ProviderName$startDate = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{ LogName='Application'; Level=2; StartTime=$startDate }Get-WinEvent -LogName System -MaxEvents 500 | Group-Object Id | Sort-Object Count -Descending | Select-Object -First 5 Count, Name$startDate = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{ LogName='Security'; StartTime=$startDate } | Export-Csv -Path "security_24h.csv" -NoTypeInformation$startDate = (Get-Date).AddDays(-7)
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4624 or EventID=4625) and TimeCreated[timediff(@SystemTime) <= 604800000]]]"