Wysyłanie zapytań do dzienników zdarzeń systemu Windows za pomocą programu PowerShell

Dziennik zdarzeń systemu Windows to ważne narzędzie dla administratorów umożliwiające śledzenie błędów, ostrzeżeń i innych raportów informacyjnych rejestrowanych przez system operacyjny, jego składniki lub programy. Można użyć graficznej przystawki MMC Podglądu zdarzeń (eventvwr.msc), aby wyświetlić dziennik zdarzeń systemu Windows. W niektórych przypadkach znacznie wygodniej jest używać programu PowerShell do analizowania i analizowania informacji z dzienników zdarzeń. W tym artykule dowiesz się, jak korzystać zZdarzenie Get-Wincmdlet, aby uzyskać informacje z dzienników zdarzeń systemu Windows.

Zawartość:

W systemie Windows dostępne są obecnie dwa polecenia cmdlet umożliwiające dostęp do wpisów dziennika zdarzeń:Pobierz dziennik zdarzeńIZdarzenie Get-Win.W większości przypadków zalecamy użycie Get-WinEvent, ponieważ jest ono bardziej produktywne, szczególnie w scenariuszach, w których trzeba przetworzyć dużą liczbę zdarzeń z komputerów zdalnych. Polecenie cmdlet Get-EventLog jest przestarzałe i było używane do pobierania dzienników we wcześniejszych wersjach systemu Windows. Ponadto metoda Get-EventLog nie jest obsługiwana w najnowszych wersjach programu PowerShell Core 7.x.

Get-WinEvent: przeszukaj dzienniki zdarzeń za pomocą programu PowerShell

Aby użyć polecenia Get-WinEvent, musisz uruchomić PowerShell jako administrator. Jeśli spróbujesz uruchomić Get-WinEvent jako użytkownik inny niż administrator, nie będziesz mieć dostępu do niektórych dzienników, w tym dzienników zabezpieczeń.

Aby uzyskać listę zdarzeń z konkretnego dziennika, należy podać jego nazwę. Na przykład poniższe polecenie wyświetla listę 20 ostatnich zdarzeń z dziennika systemowego:

Get-WinEvent -LogName Application -MaxEvents 20

Dzienniki systemu, aplikacji, zabezpieczeń i konfiguracji to dzienniki, do których najczęściej należy się odpytywać. Można także określić inne nazwy dzienników. Pełną listę dzienników zdarzeń w systemie Windows można uzyskać za pomocą polecenia:

Get-WinEvent -ListLog *

Na przykład, aby wyświetlić historię połączeń RDP na komputerze, należy określićMicrosoft-Windows-TerminalServices-RemoteConnectionManager/Operationaldziennik:

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

Możesz też uzyskać dzienniki połączeń SSH w systemie Windows z dziennika OpenSSH/operacyjnego:

Get-WinEvent -LogName OpenSSH/Operational

Możesz także wybrać zdarzenia z wielu dzienników jednocześnie. Przykładowo, jeśli chcesz uzyskać informacje o błędach i ostrzeżeniach z logów Systemu i Aplikacji z ostatnich 24 godzin, użyj poniższego kodu:

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

Aby wyświetlić tylko określone pola zdarzeń, można użyć poleceń cmdlet Select-Object lub Format-Table:

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

Dane uzyskane z dziennika zdarzeń możesz dalej przetwarzać. W tym przykładzie od razu przekonwertujemy nazwę użytkownika na SID:

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

Szybkie wyszukiwanie zdarzeń dzięki opcji FilterHashtable

Powyższa metoda filtrowania określonych zdarzeń z dzienników Podglądu zdarzeń za pomocą Where-Object może być łatwa do zrozumienia, ale jest niezwykle powolna, szczególnie jeśli chcesz przeszukać dużą liczbę zdarzeń. W większości przypadków lepiej jest użyć filtrowania po stronie serwera Podglądu zdarzeń za pomocąFiltrujHashtableopcja.

Teraz spróbujmy wygenerować listę błędów i ostrzeżeń na okres 30 dni, korzystając z Where-Object i FilterHashtable. Skorzystamy wtedyMeasure-Commandaby porównać czas wykonania tych dwóch poleceń PowerShell:

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

Najpierw sprawdzamy czas wykonania polecenia za pomocą filtra Where-Object:

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

To samo polecenie z FilterHashtable:

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

Ten przykład pokazuje, że polecenie filtrowania zdarzeń FilterHashtable to:30 razy szybciejniż zwykły filtr Where-Object (2.5sekundy vs76sekundy).

Jeśli chcesz znaleźć zdarzenia według EventID, użyj następującego polecenia z parametrem FilterHashtable:

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

W tym przykładzie otrzymaliśmy najnowsze zdarzenia ponownego uruchomienia i zamknięcia systemu Windows, co pozwala nam określić, kto ponownie uruchomił lub zamknął komputer z systemem Windows.

Argument FilterHashtable umożliwia filtrowanie według następujących atrybutów zdarzenia:

  • Nazwa dziennika
  • Nazwa dostawcy
  • Ścieżka
  • Słowa kluczowe (użyj 9007199254740992, aby wyszukać udane wydarzenia i 4503599627370496, aby wyszukać nieudane)
  • ID
  • Poziom (1=FATALNY, 2=BŁĄD, 3=Ostrzeżenie, 4=Informacja, 5=DEBUGOWANIE, 6=TRACE, 0=Informacja)
  • Czas rozpoczęcia
  • Koniec
  • UserID (identyfikator użytkownika)
  • Dane

Oto przykład wyszukiwania wydarzenia w określonym przedziale czasu:

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

Jeśli chcesz znaleźć konkretny tekst w opisie wydarzenia, możesz użyć poniższego polecenia:

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

Zaawansowane filtrowanie zdarzeń Get-WinEvent za pomocą FilterXml

Filtry Get-WinEvent z opcją FilterHashtable mają pewne ograniczenia. Jeśli chcesz używać złożonych zapytań z wieloma kryteriami do wybierania zdarzeń, musisz użyćFiltrXmlflagę, która umożliwia dokonanie wyboru za pomocą zapytania XML. Podobnie jak FilterHashtable, filtry FilterXml działają po stronie serwera. Oznacza to, że wynik otrzymasz dość szybko.

Oto na przykład inny sposób uzyskania najnowszych błędów z dziennika systemowego z ostatnich 30 dni:

$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

Aby wygenerować złożony kod zapytania XML, możesz użyć konsoli graficznej Podglądu zdarzeń:

  1. Uruchom polecenieeventvwr.msc;
  2. Znajdź dziennik, dla którego chcesz utworzyć zapytanie, i kliknijFiltruj bieżący dziennik;
  3. W formularzu filtra wybierz wymagane parametry zapytania. W tym przykładzie chcę znaleźć wydarzenia o określonych identyfikatorach EventID z ostatnich 7 dni dla konkretnego użytkownika;
  4. Aby uzyskać kod zapytania XML, przejdź do karty XML i skopiuj kod XPath (CTRL+A,CTRL+C);
  5. W razie potrzeby możesz edytować to zapytanie ręcznie.

Aby wyeksportować listę zdarzeń do pliku CSV, użyj polecenia cmdlet Export-CSV:

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

Pobierz dzienniki zdarzeń z komputerów zdalnych

Aby pobrać zdarzenia z komputera zdalnego, wystarczy podać jego nazwę w pliku-Nazwa komputeraparametr:

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

Możesz wysyłać zapytania do wielu zdalnych hostów jednocześnie, aby wyszukać określone zdarzenia. Listę komputerów zdalnych możesz uzyskać z pliku tekstowego:

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

Lub z 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
}

Oto kolejny przykład wyszukiwania zdarzeń blokady kont użytkowników na wszystkich kontrolerach domeny:

Sugerowana lektura:Jak zapisywać dzienniki w Podglądzie zdarzeń systemu Windows z programu PowerShell/CMD

$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