Interrogazione dei registri eventi di Windows con PowerShell

Il registro eventi di Windows è uno strumento importante che consente agli amministratori di tenere traccia di errori, avvisi e altri rapporti informativi registrati dal sistema operativo, dai suoi componenti o dai programmi. È possibile utilizzare lo snap-in grafico MMC Visualizzatore eventi (eventvwr.msc) per visualizzare il registro eventi di Windows. In alcuni casi, è molto più conveniente utilizzare PowerShell per analizzare le informazioni dai registri eventi. In questo articolo imparerai come utilizzare il fileGet-WinEventcmdlet per ottenere informazioni dai registri eventi di Windows.

Contenuto:

In Windows sono attualmente disponibili due cmdlet per l'accesso alle voci del registro eventi:Get-EventLogEGet-WinEvent.Ti consigliamo di utilizzare Get-WinEvent nella maggior parte dei casi perché è più produttivo, soprattutto negli scenari in cui è necessario elaborare un numero elevato di eventi da computer remoti. Il cmdlet Get-EventLog è deprecato e veniva utilizzato per ottenere i log nelle versioni precedenti di Windows. Inoltre, Get-EventLog non è supportato nelle versioni più recenti di PowerShell Core 7.x.

Get-WinEvent: cerca nei registri eventi utilizzando PowerShell

Per utilizzare il comando Get-WinEvent, è necessario eseguire PowerShell come amministratore. Se provi a eseguire Get-WinEvent come utente non amministratore, non sarai in grado di accedere a determinati registri, inclusi i registri di sicurezza.

Per ottenere un elenco di eventi da un registro specifico, è necessario specificarne il nome. Ad esempio, il comando seguente elenca gli ultimi 20 eventi dal registro di sistema:

Get-WinEvent -LogName Application -MaxEvents 20

I registri di sistema, applicazione, sicurezza o configurazione sono i registri più comuni su cui eseguire query. È inoltre possibile specificare altri nomi di registro. Puoi ottenere un elenco completo dei registri eventi in Windows con il comando:

Get-WinEvent -ListLog *

Ad esempio, per visualizzare la cronologia delle connessioni RDP su un computer, è necessario specificare il fileMicrosoft-Windows-TerminalServices-RemoteConnectionManager/Operationaltronco d'albero:

Get-WinEvent -LogName Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational

Oppure puoi ottenere i log di connessione SSH in Windows dal registro OpenSSH/Operational:

Get-WinEvent -LogName OpenSSH/Operational

Puoi anche selezionare eventi da più registri contemporaneamente. Ad esempio, se desideri ottenere informazioni su errori e avvisi dai registri di sistema e dell'applicazione delle ultime 24 ore, utilizza il seguente codice:

$StartDate = (Get-Date) - (New-TimeSpan -Day 1)
Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}

È possibile utilizzare i cmdlet Select-Object o Format-Table per visualizzare solo campi evento specifici:

Get-WinEvent -LogName System | Format-Table Machinename, TimeCreated, Id, UserID

È possibile elaborare ulteriormente i dati ottenuti dal registro eventi. In questo esempio, convertiremo immediatamente il nome utente in SID:

Get-WinEvent -filterhash @{Logname="system"} |
Select-Object @{Name="Computername";Expression = {$_.machinename}},@{Name="UserName";Expression = {$_.UserId.translate([System.Security.Principal.NTAccount]).value}}, TimeCreated

Ricerca rapida degli eventi con l'opzione FilterHashtable

Il metodo sopra descritto per filtrare eventi specifici dai registri del Visualizzatore eventi con Where-Object può essere facile da comprendere, ma è estremamente lento, soprattutto se si desidera eseguire la ricerca in un numero elevato di eventi. Nella maggior parte dei casi, è preferibile utilizzare il filtro lato server del Visualizzatore eventi utilizzando il fileFilterHashtableopzione.

Ora proviamo a generare un elenco di errori e avvisi in un periodo di 30 giorni utilizzando Where-Object e FilterHashtable. Utilizzeremo quindiMeasure-Commandper confrontare il tempo di esecuzione di questi due comandi di PowerShell:

$StartDate = (Get-Date).AddDays(-30)

Per prima cosa controlliamo il tempo di esecuzione del comando con il filtro Where-Object:

(Measure-Command {Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}}).TotalMilliseconds

Lo stesso comando con FilterHashtable:

(Measure-Command {Get-WinEvent -FilterHashtable @{LogName="System",'Application'; Level =2,3; StartTime=$StartDate }}).TotalMilliseconds

Questo esempio mostra che il comando di filtraggio eventi FilterHashtable è30 volte più velocerispetto al solito filtro Where-Object (2.5secondi contro76secondi).

Se devi trovare eventi in base a EventID, utilizza il comando seguente con il parametro FilterHashtable:

Get-WinEvent -FilterHashtable @{logname="System";id=1074}|ft TimeCreated,Id,Message

In questo esempio, abbiamo ricevuto gli ultimi eventi di riavvio e arresto di Windows, consentendoci di determinare chi ha riavviato o spento il computer Windows.

L'argomento FilterHashtable consente di filtrare in base ai seguenti attributi dell'evento:

  • NomeRegistro
  • Nomefornitore
  • Sentiero
  • Parole chiave (usa 9007199254740992 per cercare eventi riusciti e 4503599627370496 per quelli falliti)
  • ID
  • Livello (1=FATAL, 2=ERRORE, 3=Avviso, 4=Informazioni, 5=DEBUG, 6=TRACE, 0=Informazioni)
  • Ora di inizio
  • Ora di fine
  • UserID (SID dell'utente)
  • Dati

Ecco un esempio di ricerca di un evento in un determinato periodo di tempo:

Get-WinEvent -FilterHashTable @{LogName="System"; StartTime=(get-date).AddDays(-7); EndTime=(get-date).AddHours(-1); ID=1234}

Il comando seguente può essere utilizzato se desideri trovare un testo specifico nella descrizione dell'evento:

Per saperne di più:Come scrivere registri nel Visualizzatore eventi di Windows da PowerShell/CMD

Get-WinEvent -FilterHashtable @{logname="System"}|Where {$_.Message -like "*USB*"}

Filtraggio avanzato Get-WinEvent con FilterXml

I filtri Get-WinEvent con l'opzione FilterHashtable presentano alcune limitazioni. Se è necessario utilizzare query complesse con molti criteri in base ai quali selezionare gli eventi, è necessario utilizzare il metodoFiltroXmlflag, che consente di effettuare la selezione utilizzando una query XML. Simile a FilterHashtable, i filtri FilterXml sono lato server. Ciò significa che ottieni il risultato abbastanza rapidamente.

Ad esempio, ecco un altro modo per ottenere gli errori più recenti dal registro di sistema degli ultimi 30 giorni:

$xmlQuery = @'
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[(Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) &lt;= 2592000000]]]</Select>
</Query>
</QueryList>
'@
Get-WinEvent -FilterXML $xmlQuery

Per generare un codice di query XML complesso, è possibile utilizzare la console grafica del Visualizzatore eventi:

  1. Esegui il comandoeventvwr.msc;
  2. Trova il log per il quale desideri creare una query e fai clic suFiltra il registro corrente;
  3. Seleziona i parametri di query richiesti nel modulo di filtro. In questo esempio, desidero trovare eventi con EventID specifici negli ultimi 7 giorni per un utente specifico;
  4. Per ottenere il codice della query XML, vai alla scheda XML e copia il codice XPath (CTRL+A,CTRL+C);
  5. Se necessario, è possibile modificare manualmente questa query.

Per esportare l'elenco degli eventi in un file CSV, utilizzare il cmdlet Export-CSV:

$Events= Get-WinEvent -FilterXML $xmlQuery
$events| Export-CSV "C:psFilterSYSEvents.csv" -NoTypeInformation -Encoding UTF8

Ottieni registri eventi da computer remoti

Per ottenere eventi da un computer remoto, è sufficiente specificarne il nome nel file-NomeComputerparametro:

$computer="mun-dc01"
Get-WinEvent -ComputerName $computer -FilterHashtable @{LogName="System"; StartTime=(get-date).AddHours(-24)} |   select Message,Id,TimeCreated

Puoi interrogare più host remoti contemporaneamente per cercare eventi specifici. Puoi ottenere l'elenco dei computer remoti da un file di testo:

$servers = Get-Content -Path C:psservers.txt

Oppure da Active Directory:

$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
}

Ecco un altro esempio di ricerca di eventi di blocco degli account utente su tutti i controller di 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}
}

Related Posts