Consulta de registros de eventos de Windows con PowerShell
El registro de eventos de Windows es una herramienta importante para que los administradores realicen un seguimiento de errores, advertencias y otros informes de información registrados por el sistema operativo, sus componentes o programas. Puede usar el complemento MMC gráfico Visor de eventos (
eventvwr.msc) para ver el registro de eventos de Windows. En algunos casos, es mucho más conveniente usar PowerShell para analizar y analizar información de los registros de eventos. En este artículo, aprenderá a usar el cmdlet Get-WinEvent para obtener información de los registros de eventos de Windows.
Dos cmdlets para acceder a las entradas del registro de eventos están actualmente disponibles en Windows: Get-EventLog y Get-WinEvent. Recomendamos que use Get-WinEvent en la mayoría de los casos, ya que es más productivo, especialmente en escenarios donde necesita procesar una gran cantidad de eventos desde computadoras remotas. El cmdlet Get-EventLog está en desuso y se usaba para obtener registros en versiones anteriores de Windows. Además, Get-EventLog no es compatible con las últimas versiones de PowerShell Core 7.x.
Get-WinEvent: Busque los registros de eventos usando PowerShell
Para usar el comando Get-WinEvent, debe ejecutar PowerShell como administrador. Si intenta ejecutar Get-WinEvent como usuario no administrador, no podrá acceder a ciertos registros, incluidos los registros de seguridad.
Para obtener una lista de eventos de un registro específico, debe especificar su nombre. Por ejemplo, el siguiente comando enumera los últimos 20 eventos del registro del sistema:
Get-WinEvent -LogName Application -MaxEvents 20Los registros del sistema, aplicación, seguridad o configuración son los registros más comunes para consultar. También puede especificar otros nombres de registro. Puede obtener una lista completa de registros de eventos en Windows con el comando:
Get-WinEvent -ListLog *Por ejemplo, para ver el historial de conexión RDP en una computadora, debe especificar el
Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operationalregistro:
Get-WinEvent -LogName Microsoft-Windows-TerminalServices-RemoteConnectionManager/OperationalO puede obtener los registros de conexión SSH en Windows desde el registro OpenSSH/Operational:
Get-WinEvent -LogName OpenSSH/OperationalTambién puede seleccionar eventos de varios registros a la vez. Por ejemplo, si desea obtener información sobre errores y advertencias de los registros del sistema y de la aplicación durante las últimas 24 horas, use el siguiente código:
$StartDate = (Get-Date) - (New-TimeSpan -Day 1)
Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}Puede usar los cmdlets Select-Object o Format-Table para mostrar solo campos de eventos específicos:
Get-WinEvent -LogName System | Format-Table Machinename, TimeCreated, Id, UserIDPuede seguir procesando los datos obtenidos del registro de eventos. En este ejemplo, convertiremos inmediatamente el nombre de usuario a SID:
Get-WinEvent -filterhash @{Logname = 'system'} |
Select-Object @{Name="Computername";Expression = {$_.machinename}},@{Name="UserName";Expression = {$_.UserId.translate([System.Security.Principal.NTAccount]).value}}, TimeCreatedBúsqueda rápida de eventos con la opción FilterHashtable
El método anterior para filtrar eventos específicos de los registros del Visor de eventos con Where-Object puede ser fácil de entender, pero es extremadamente lento, especialmente si desea buscar en una gran cantidad de eventos. En la mayoría de los casos, es mejor usar el filtro del lado del servidor del Visor de eventos usando la opción FilterHashtable.
Ahora, intentemos generar una lista de errores y advertencias durante un período de 30 días usando Where-Object y FilterHashtable. Entonces usaremos
Measure-Commandpara comparar el tiempo de ejecución de estos dos comandos de PowerShell:
$StartDate = (Get-Date).AddDays(-30)Primero, comprobamos el tiempo de ejecución del comando con el filtro Where-Object:
(Measure-Command {Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}}).TotalMillisecondsEl mismo comando con FilterHashtable:
(Measure-Command {Get-WinEvent -FilterHashtable @{LogName = 'System','Application'; Level =2,3; StartTime=$StartDate }}).TotalMillisecondsEste ejemplo muestra que el comando de filtrado de eventos FilterHashtable es 30 veces más rápido que el filtro Where-Object habitual (
2.5segundos vs
76segundos).
Si necesita buscar eventos por EventID, use el siguiente comando con el parámetro FilterHashtable:
Get-WinEvent -FilterHashtable @{logname='System';id=1074}|ft TimeCreated,Id,MessageEn este ejemplo, hemos recibido los últimos eventos de reinicio y apagado de Windows, lo que nos permite determinar quién reinició o apagó la máquina con Windows.
El argumento FilterHashtable le permite filtrar por los siguientes atributos de evento:
- LogName
- ProviderName
- Path
- Keywords (use 9007199254740992 to search for successful events and 4503599627370496 for failed ones)
- ID
- Level (1=FATAL, 2=ERROR, 3=Warning, 4=Information, 5=DEBUG, 6=TRACE, 0=Info)
- StartTime
- EndTime
- UserID (user’s SID)
- Data
Utilice las palabras clave 9007199254740992 para buscar eventos exitosos y 4503599627370496 para los fallidos.
Aquí hay un ejemplo de búsqueda de un evento durante un cierto período de tiempo:
Get-WinEvent -FilterHashTable @{LogName='System'; StartTime=(get-date).AddDays(-7); EndTime=(get-date).AddHours(-1); ID=1234}El siguiente comando se puede usar si desea encontrar un texto específico en la descripción del evento:
Get-WinEvent -FilterHashtable @{logname='System'}|Where {$_.Message -like "*USB*"}Filtrado avanzado Get-WinEvent con FilterXml
Los filtros Get-WinEvent con la opción FilterHashtable tienen algunas limitaciones. Si necesita utilizar consultas complejas con muchos criterios para seleccionar eventos, debe utilizar el indicador FilterXml, que le permite realizar la selección mediante una consulta XML. Similar a FilterHashtable, los filtros FilterXml están en el lado del servidor. Esto significa que obtienes el resultado bastante rápido.
Por ejemplo, aquí hay otra forma de obtener los errores más recientes del registro del sistema durante los últimos 30 días:
$xmlQuery = @'
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[(Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) <= 2592000000]]]</Select>
</Query>
</QueryList>
'@
Get-WinEvent -FilterXML $xmlQueryPara generar un código de consulta XML complejo, puede utilizar la consola gráfica del Visor de eventos:
Ejecute el comando
eventvwr.msc;
Busque el registro para el que desea crear una consulta y haga clic en Filtrar registro actual;
Seleccione los parámetros de consulta requeridos en el formulario de filtro. En este ejemplo, quiero encontrar eventos con ID de evento específicos durante los últimos 7 días para un usuario específico;
Para obtener el código de consulta XML, vaya a la pestaña XML y copie el código XPath (
CTRL+A,
CTRL+C);
Puede editar esta consulta manualmente si es necesario.
Para exportar la lista de eventos a un archivo CSV, use el cmdlet Export-CSV:
$Events= Get-WinEvent -FilterXML $xmlQuery
$events| Export-CSV "C:\ps\FilterSYSEvents.csv" -NoTypeInformation -Encoding UTF8Obtenga registros de eventos de computadoras remotas
Para obtener eventos de una computadora remota, simplemente especifique su nombre en el parámetro -ComputerName:
$computer='mun-dc01'
Get-WinEvent -ComputerName $computer -FilterHashtable @{LogName="System"; StartTime=(get-date).AddHours(-24)} | select Message,Id,TimeCreatedPuede consultar varios hosts remotos a la vez para buscar eventos específicos. Puede obtener la lista de equipos remotos desde un archivo de texto:
$servers = Get-Content -Path C:\ps\servers.txtO desde el Directorio Activo:
$servers = (Get-ADComputer -Filter 'operatingsystem -like "*Windows Server*" -and enabled -eq "true"').Name
foreach ($server in $servers) {
Get-WinEvent -ComputerName $server -MaxEvents 5 -FilterHashtable @{
LogName = 'System'; ID= 1234
} | Select-Object -Property ID, MachineName
}Este es otro ejemplo de búsqueda de eventos de bloqueo de cuenta de usuario en todos los controladores de dominio:
$Username = 'a.muller'
Get-ADDomainController -fi * | select -exp hostname | % {
$GweParams = @{
'Computername' = $_
'LogName' = 'Security'
'FilterXPath' = "*[System[EventID=4740] and EventData[Data[@Name='TargetUserName']='$Username']]"
}
$Events = Get-WinEvent @GweParams
$Events | foreach {$_.Computer + " " +$_.Properties[1].value + ' ' + $_.TimeCreated}
}







