PowerShell ile Windows Olay Günlüklerini Sorgulama
Windows Olay Günlüğü, yöneticilerin işletim sistemi, bileşenleri veya programları tarafından günlüğe kaydedilen hataları, uyarıları ve diğer bilgi raporlarını izlemesi için önemli bir araçtır. Olay Görüntüleyici grafik MMC ek bileşenini kullanabilirsiniz (
eventvwr.msc) Windows olay günlüğünü görüntülemek için. Bazı durumlarda, Olay Günlüklerinden bilgileri ayrıştırmak ve analiz etmek için PowerShell'i kullanmak çok daha uygundur. Bu makalede, Windows olay günlüklerinden bilgi almak için Get-WinEvent cmdlet'ini nasıl kullanacağınızı öğreneceksiniz.
Olay günlüğü girişlerine erişmek için şu anda Windows'ta iki cmdlet bulunmaktadır: Get-EventLog ve Get-WinEvent. Get-WinEvent'i çoğu durumda, özellikle uzak bilgisayarlardan çok sayıda olayı işlemeniz gereken senaryolarda daha üretken olduğundan kullanmanızı öneririz. Get-EventLog cmdlet'i kullanımdan kaldırılmıştır ve Windows'un önceki sürümlerinde günlükleri almak için kullanılmıştır. Ayrıca Get-EventLog, PowerShell Core 7.x'in en son sürümlerinde desteklenmez.
Get-WinEvent: PowerShell Kullanarak Olay Günlüklerini Arayın
Get-WinEvent komutunu kullanmak için PowerShell'i yönetici olarak çalıştırmalısınız. Get-WinEvent'i yönetici olmayan bir kullanıcı olarak çalıştırmayı denerseniz, Güvenlik günlükleri de dahil olmak üzere belirli günlüklere erişemezsiniz.
Belirli bir günlükten olayların listesini almak için adını belirtmeniz gerekir. Örneğin, aşağıdaki komut Sistem günlüğündeki son 20 olayı listeler:
Get-WinEvent -LogName Application -MaxEvents 20Sistem, Uygulama, Güvenlik veya Kurulum günlükleri, sorgulanacak en yaygın günlüklerdir. Diğer günlük adlarını da belirleyebilirsiniz. Aşağıdaki komutla Windows'ta olay günlüklerinin tam bir listesini alabilirsiniz:
Get-WinEvent -ListLog *Örneğin, bir bilgisayarda RDP bağlantı geçmişini görüntülemek için,
Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operationalkayıt:
Get-WinEvent -LogName Microsoft-Windows-TerminalServices-RemoteConnectionManager/OperationalVeya Windows'ta SSH bağlantı günlüklerini OpenSSH/Operational günlüğünden alabilirsiniz:
Get-WinEvent -LogName OpenSSH/OperationalAynı anda birden çok günlükten olayları da seçebilirsiniz. Örneğin, Sistem ve Uygulama günlüklerinden son 24 saate ait hatalar ve uyarılar hakkında bilgi almak istiyorsanız aşağıdaki kodu kullanın:
$StartDate = (Get-Date) - (New-TimeSpan -Day 1)
Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}Yalnızca belirli olay alanlarını görüntülemek için Select-Object veya Format-Table cmdlet'lerini kullanabilirsiniz:
Get-WinEvent -LogName System | Format-Table Machinename, TimeCreated, Id, UserIDOlay günlüğünden elde edilen verileri daha fazla işleyebilirsiniz. Bu örnekte, kullanıcı adını hemen SID'ye dönüştüreceğiz:
Get-WinEvent -filterhash @{Logname = 'system'} |
Select-Object @{Name="Computername";Expression = {$_.machinename}},@{Name="UserName";Expression = {$_.UserId.translate([System.Security.Principal.NTAccount]).value}}, TimeCreatedFilterHashtable Seçeneği ile Hızlı Olay Arama
Olay Görüntüleyicisi günlüklerinden belirli olayları Where-Object ile filtrelemek için yukarıdaki yöntemin anlaşılması kolay olabilir, ancak özellikle çok sayıda olay arasında arama yapmak istiyorsanız son derece yavaştır. Çoğu durumda FilterHashtable seçeneğini kullanarak Event Viewer sunucu tarafı filtrelemeyi kullanmak daha iyidir.
Şimdi Where-Object ve FilterHashtable kullanarak 30 günlük bir hata ve uyarı listesi oluşturmaya çalışalım. sonra kullanacağız
Measure-Commandbu iki PowerShell komutunun yürütme süresini karşılaştırmak için:
$StartDate = (Get-Date).AddDays(-30)İlk olarak, komutun yürütülme zamanını Where-Object filtresiyle kontrol ediyoruz:
(Measure-Command {Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}}).TotalMillisecondsFilterHashtable ile aynı komut:
(Measure-Command {Get-WinEvent -FilterHashtable @{LogName = 'System','Application'; Level =2,3; StartTime=$StartDate }}).TotalMillisecondsBu örnek, FilterHashtable olay filtreleme komutunun, normal Nerede-Nesne filtresinden 30 kat daha hızlı olduğunu gösterir (
2.5saniye vs
76saniye).
EventID'ye göre olayları bulmanız gerekiyorsa, FilterHashtable parametresiyle aşağıdaki komutu kullanın:
Get-WinEvent -FilterHashtable @{logname='System';id=1074}|ft TimeCreated,Id,MessageBu örnekte, Windows makinesini kimin yeniden başlattığını veya kapattığını belirlememizi sağlayan en son Windows yeniden başlatma ve kapatma olaylarını aldık.
FilterHashtable bağımsız değişkeni, aşağıdaki olay özniteliklerine göre filtrelemenize olanak tanır:
- 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
Başarılı olayları aramak için 9007199254740992 ve başarısız olanlar için 4503599627370496 anahtar kelimelerini kullanın.
Aşağıda, belirli bir süre boyunca bir etkinlik aramaya ilişkin bir örnek verilmiştir:
Get-WinEvent -FilterHashTable @{LogName='System'; StartTime=(get-date).AddDays(-7); EndTime=(get-date).AddHours(-1); ID=1234}Olay açıklamasında belirli bir metni bulmak istiyorsanız aşağıdaki komut kullanılabilir:
Get-WinEvent -FilterHashtable @{logname='System'}|Where {$_.Message -like "*USB*"}FilterXml ile Gelişmiş Get-WinEvent Filtreleme
FilterHashtable seçeneğine sahip Get-WinEvent filtrelerinin bazı sınırlamaları vardır. Olayları seçmek için birçok ölçüte sahip karmaşık sorgular kullanmanız gerekiyorsa, bir XML sorgusu kullanarak seçim yapmanıza olanak tanıyan FilterXml işaretini kullanmanız gerekir. FilterHashtable'a benzer şekilde, FilterXml filtreleri sunucu tarafındadır. Bu, sonucu oldukça hızlı bir şekilde alacağınız anlamına gelir.
Örneğin, son 30 güne ait Sistem günlüğünden en son hataları almanın başka bir yolu:
$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 $xmlQueryKarmaşık bir XML sorgu kodu oluşturmak için Olay Görüntüleyicisi grafik konsolunu kullanabilirsiniz:
komutu çalıştır
eventvwr.msc;
Sorgu oluşturmak istediğiniz günlüğü bulun ve Mevcut Günlüğü Filtrele'yi tıklayın;
Filtre formunda gerekli sorgu parametrelerini seçin. Bu örnekte, belirli bir kullanıcı için son 7 güne ait belirli EventID'lere sahip etkinlikleri bulmak istiyorum;
XML sorgu kodunu almak için XML sekmesine gidin ve XPath kodunu kopyalayın (
CTRL+A,
CTRL+C);
Gerekirse bu sorguyu manuel olarak düzenleyebilirsiniz.
Olay listesini bir CSV dosyasına vermek için Export-CSV cmdlet'ini kullanın:
$Events= Get-WinEvent -FilterXML $xmlQuery
$events| Export-CSV "C:\ps\FilterSYSEvents.csv" -NoTypeInformation -Encoding UTF8Uzak Bilgisayarlardan Olay Günlüklerini Alın
Olayları uzak bir bilgisayardan almak için -ComputerName parametresinde adını belirtmeniz yeterlidir:
$computer='mun-dc01'
Get-WinEvent -ComputerName $computer -FilterHashtable @{LogName="System"; StartTime=(get-date).AddHours(-24)} | select Message,Id,TimeCreatedBelirli olayları aramak için birden fazla uzak ana bilgisayarı aynı anda sorgulayabilirsiniz. Uzak bilgisayarların listesini bir metin dosyasından alabilirsiniz:
$servers = Get-Content -Path C:\ps\servers.txtVeya Active Directory'den:
$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
}Burada, tüm etki alanı denetleyicilerinde kullanıcı hesabı kilitleme olaylarını aramanın başka bir örneği verilmiştir:
$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}
}







