A Windows Vista / Server 2008 verziók óta újabb eseménynaplókkal bővült a rendszer. Az alábbi képen látható, hogy az Event Viewer alkalmazásban ezek hol találhatók:
112 . ábra Alkalmazás- és szolgáltatásnaplók
Ez egy nagyon sok naplót tartalmazó rész, amelyeket a Get-EventLog nem kezel, ezzel szemben a Get-WinEvent igen. Ez a cmdlet kicsit más szintaxissal és lehetőségekkel rendelkezik. Nézzünk pár példát a használatára. A lehetséges napló kategóriák kilistázásához a –ListLog paraméter használható, viszont kötelező valamit megadni, akár egy *-ot:
[5] PS C:\> Get-WinEvent -ListLog *
LogName MaximumSizeInBytes RecordCount LogMode
------- ------------------ ----------- -------
Active Directory... 1052672 36 Circular
Application 20971520 931 Circular
…
Nézzük meg egy konkrét naplókategória jellemzőit:
[31] PS C:\> Get-WinEvent -Listlog "Microsoft-Windows-WinRM/Operational" | fl *
FileSize : 1052672
IsLogFull : False
LastAccessTime : 2009. 11. 09. 21:13:04
LastWriteTime : 2009. 12. 31. 15:14:07
OldestRecordNumber : 77489
RecordCount : 2500
LogName : Microsoft-Windows-WinRM/Operational
LogType : Operational
LogIsolation : Application
IsEnabled : True
IsClassicLog : False
SecurityDescriptor : O:BAG:SYD:(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0
x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S
-1-5-3)(A;;0x3;;;S-1-5-33)(A;;0x1;;;S-1-5-32-
573)
LogFilePath : %SystemRoot%\System32\Winevt\Logs\Microsoft-W
indows-WinRM%4Operational.evtx
MaximumSizeInBytes : 1052672
LogMode : Circular
OwningProviderName : Microsoft-Windows-WinRM
ProviderNames : {Microsoft-Windows-WinRM}
ProviderLevel :
ProviderKeywords :
ProviderBufferSize : 64
ProviderMinimumNumberOfBuffers : 0
ProviderMaximumNumberOfBuffers : 64
ProviderLatency : 1000
ProviderControlGuid :
Egyes logok bejegyzéseinek listázásához szűrőfeltételek akár hashtábla formátumban is megadhatók:
[18] PS C:\> Get-WinEvent -FilterHashtable @{id = 169; logname="Microsoft-Windo
ws-WinRM/Operational"}
TimeCreated ProviderName Id Message
----------- ------------ -- -------
2009. 12. 13. 12... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 22... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 22... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 22... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 22... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 21... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 21... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 21... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 21... Microsoft-Window... 169 User R2\hh auth...
2009. 12. 07. 21... Microsoft-Window... 169 User R2\Adminis...
2009. 12. 07. 21... Microsoft-Window... 169 User R2\Adminis...
Látható, hogy itt kicsit másak az esemény tulajdonságainak a nevei, például nem EventID, hanem csak ID. Nézzük meg, hogy egy bejegyzés hogyan néz ki részletesen:
[19] PS C:\> (Get-WinEvent -FilterHashtable @{id = 169; logname="Microsoft-Wind
ows-WinRM/Operational"})[0] | fl *
Message : User R2\hh authenticated successfully using Kerberos au
thentication
Id : 169
Version : 0
Qualifiers :
Level : 4
Task : 7
Opcode : 0
Keywords : 4611686018427387916
RecordId : 79980
ProviderName : Microsoft-Windows-WinRM
ProviderId : a7975c8f-ac13-49f1-87da-5a984a4ab417
LogName : Microsoft-Windows-WinRM/Operational
ProcessId : 248
ThreadId : 2780
MachineName : dc.r2.dom
UserId : S-1-5-20
TimeCreated : 2009. 12. 13. 12:34:24
ActivityId : 00000100-0000-0000-1f05-9ad1b17aca01
RelatedActivityId :
ContainerLog : microsoft-windows-winrm/operational
MatchedQueryIds : {}
Bookmark : System.Diagnostics.Eventing.Reader.EventBookmark
LevelDisplayName : Information
OpcodeDisplayName : Info
TaskDisplayName : User authentication
KeywordsDisplayNames : {Server, Security}
Properties : {System.Diagnostics.Eventing.Reader.EventProperty, Syst
em.Diagnostics.Eventing.Reader.EventProperty}
Látható az is, hogy itt nem a ReplacementStrings tulajdonság, hanem a Properties tartalmazza a futás időben generálódó információkat. Nézzük meg ezt is:
[20] PS C:\> (Get-WinEvent -FilterHashtable @{id = 169; logname="Microsoft-Wind
ows-WinRM/Operational"})[0].properties
Value
-----
R2\hh
Kerberos
Innentől már hasonlóan lehet például informatív táblázatokat készíteni. Itt most konkrétan a WinRM szolgáltatás igénybevételével kapcsolatos statisztikát készítettem az eseménynapló bejegyzései alapján:
[27] PS C:\> Get-WinEvent -FilterHashtable @{id = 169; logname="Microsoft-Windo
ws-WinRM/Operational"} | Select-Object -Property TimeCreated, @{n="User";e={$_.
properties[0].value}}
TimeCreated User
----------- ----
2009. 12. 13. 12:34:24 R2\hh
2009. 12. 07. 22:06:02 R2\hh
2009. 12. 07. 22:02:23 R2\hh
2009. 12. 07. 22:00:51 R2\hh
2009. 12. 07. 22:00:15 R2\hh
2009. 12. 07. 21:58:47 R2\hh
2009. 12. 07. 21:58:19 R2\hh
2009. 12. 07. 21:54:08 R2\hh
2009. 12. 07. 21:54:02 R2\hh
2009. 12. 07. 21:49:21 R2\Administrator
2009. 12. 07. 21:49:12 R2\Administrator
Vagy hasonló módon lehet kigyűjteni azt, hogy melyik frissítés mikor települt:
[35] PS C:\> Get-WinEvent -FilterHashTable @{ProviderName="Microsoft-Windows-Wi
ndowsUpdateClient"; ID=19} | Select-Object -Property timecreated, @{n="Patch";e
={$_.properties[0].value}} | ft -AutoSize
TimeCreated Patch
----------- -----
2009. 12. 28. 18:39:06 Windows Malicious Software Removal Tool x64 - Decemb...
2009. 12. 11. 23:31:19 Cumulative Security Update for Internet Explorer 8 f...
2009. 11. 25. 9:13:12 Update for Windows Server 2008 R2 x64 Edition (KB976...
2009. 11. 18. 8:59:01 Update for Internet Explorer 8 for Windows Server 20...
2009. 11. 09. 22:22:22 Security Update for Windows Server 2008 R2 x64 Editi...
2009. 11. 09. 22:22:22 Security Update for ActiveX Killbits for Windows Ser...
2009. 11. 09. 22:22:22 Security Update for Internet Explorer 8 for Windows ...
2009. 11. 09. 22:22:22 Update for Windows Server 2008 R2 x64 Edition (KB974...
2009. 11. 09. 22:22:22 Update for Windows Server 2008 R2 x64 Edition (KB974...
2009. 11. 09. 22:22:22 Security Update for Windows Server 2008 R2 x64 Editi...
2009. 11. 09. 22:22:22 Update for Internet Explorer 8 Compatibility View Li...
Megjegyzés
Ha PowerShell 3.0 vagy újabb környezetet használunk és a Get-WinEvent kimenetén a Message tulajdonság esetleg üres lenne, akkor az a .NET 4.0 keretrendszer hibájára vezethető vissza:
PS C:\> Get-WinEvent -LogName microsoft-windows-Powershell/Operational -MaxEven
ts 2
ProviderName: Microsoft-Windows-PowerShell
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
2015.01.20. 21:45:46 40962
2015.01.20. 21:45:45 40961
Ilyenkor ideiglenesen át kell váltani a nyelvi beállítást en-US-re és futtassuk így a parancsunkat:
PS C:\> [System.Threading.Thread]::CurrentThread.CurrentCulture = "en-US" ; Get
-WinEvent -LogName microsoft-windows-Powershell/Operational -MaxEvents 2
ProviderName: Microsoft-Windows-PowerShell
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
1/20/2015 9:58:25 PM 24578 Information Windows PowerShell ISE ...
1/20/2015 9:55:35 PM 24578 Information Windows PowerShell ISE ...
Fontos, hogy egy sorban van a CurrentCulture átállítása és a Get-WinEvent futtatása. Ha külön végrehajtási egységként hajtom végre a két kifejezést, akkor a Culture hatása már érvényét veszti.
Természetesen ha szkriptben alkalmazzuk ezt, akkor lehet két kölön sorban, hiszen ott a szkript a végrehajtási egység.
Az előzőekben láttuk, hogy hashtábla szintaxissal össze tudunk rakni egyszerűbb lekérdezéseket a Get‑WinEvent cmdletnél. Ha például egyszerre több naplóban szeretnénk keresni, vagy bizonyos bejegyzéseket szeretnénk kihagyni a találati listából, akkor ez a módszer már nem lesz elég. Ilyenkor jön jól egy másik lekérdezési lehetőség: az XML!
Mielőtt mindenki elborzadva átlapozná ezt a fejezetet megnyugtatásul előre bocsátom, hogy az XML kifejezések összeállításához nagy segítséget kapunk a beépített Event Viewer alkalmazástól. Nézzünk egy egyszerű szűrést a grafikus felületen, ahol a rendszerindításkor keletkező bejegyzésekre szűrök:
113 . ábra Szűrés az Event Viewerben a rendszerindítási naplóbejegyzésekre
Látható, hogy a „Kernel-General” forrásra szűrtem, ezen belül me a 12-es azonosítójú bejegyzésekre. Az eredmény valami ilyesmi lesz:
114 . ábra A megszűrt naplóbejegyzések
Hogyan tudjuk ugyanezt előállítani PowerShellel XML szűrést alkalmazva? Nagyon egyszerűen! Kattintsunk jobb egérgombbal a megszűrt eseménynapló nevére a bal oldali listában (System) és a „Filter Current Log…” menüre kattintva megnyíló dialógusablakban válasszuk az XML fület:
115 . ábra A szűrőnk XML formátumban
Itt láthatjuk azt az XML-ben megfogalmazott lekérdezést, amit egy az egyben átadhatunk a Get‑WinEvent cmdlet -FilterXML paraméterének:
PS C:\Users\Tibi> $xmlfilter = @"
>> <QueryList>
>> <Query Id="0" Path="System">
>> <Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Kernel-
General'] and (EventID=12)]]</Select>
>> </Query>
>> </QueryList>
>> "@
PS C:\Users\Tibi> Get-WinEvent -FilterXml $xmlfilter
ProviderName: Microsoft-Windows-Kernel-General
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
2017.03.18. 18:09:46 12 Information The operating system st...
2017.03.15. 23:13:57 12 Information The operating system st...
2017.03.01. 22:36:16 12 Information The operating system st...
...
A lényegi rész itt a Select csomópontban van. Megadjuk itt a Select attribútumaként, hogy melyik naplóban keresünk (System). Maga a lekérdezés az egy XPath kifejezés, amivel olyan System típusú elemeket keresünk, amelyek rendelkeznek olyan Provider-rel, aminek a Name attribútuma ’Microsoft-Windows-Kernel-General’ és amelyeknek az EventID elemük értéke 12.
Honnan tudhatjuk, hogy itt System elemek vannak és a forrásnak neve ténylegesen nem „Kernel-General”, hanem „Microsoft-Windows-Kernel-General”? Ehhez nézzünk bele egy konkrét naplóbejegyzés „nyers” változatába, amit a bejegyzés tulajdonságlapjának „Details” fülének XML nézetében látunk:
116 . ábra Egy naplóbejegyzés "nyers" nézete
Nézzük, hogyan lehetne például megtalálni a legfrissebb újra indulást jelző naplóbejegyzést közvetlenül megelőző akármelyik eseménynaplóban található naplóbejegyzést! (Ez hozzávetőlegesen megmutatja nekünk, hogy mennyi ideig állt a gépünk.) A fenti képernyőképen látható, hogy a bejegyzés ideje UTC-ben van tárolva, és egy speciális formátumot kell produkálni, ezt a következő PowerShell kifejezéssel tehetjük meg:
PS C:\> $datestartup = [datetime] "2017.03.18. 18:09:46"
PS C:\> $logdate = get-date ($datestartup.ToUniversalTime().AddSeconds(-1)) -Fo
rmat s
PS C:\> $logdate
2017-03-18T17:09:45
A $datestartup-ot a ToUniversalTime metódussal tudjuk UTC-síteni, még levonok belőle 1 másodpercet, hogy nehogy magát a rendszerindítás bejegyzését találjuk meg. A get-date formátumátalakító képességét kihasználva az „s” standard formátum pont azt adja nekünk, ami a naplóbejegyzésekhez szükséges. Ehhez már csak a Z betűt kell még hozzábiggyeszteni.
Több naplóban való kereséshez az XML kifejezésben több lekérdezést is megfogalmazhatunk:
$filter = @"
<QueryList>
<Query Id="0"
Path="Application">
<Select>*[System[TimeCreated[@SystemTime<='$($logdate)Z']]]</Select>
</Query>
<Query Id="1"
Path="System">
<Select>*[System[TimeCreated[@SystemTime<='$($logdate)Z']]]</Select>
</Query>
<Query Id="2"
Path="Security">
<Select>*[System[TimeCreated[@SystemTime<='$($logdate)Z']]]</Select>
</Query>
</QueryList>
"@
Az elsőben az Application, a másodikban a System, a harmadikban a Security logban keresek. Miután XML-ben vagyunk, a <, > jeleket nem használhatjuk a feltételeknél, hiszen ezek XML tag-eket jelölnének. Ezért a < helyett <-t, a > helyett >-t kell használjunk. Mikor ezt futtattam, akkor ezt kaptam:
PS C:\> Get-WinEvent -FilterXml $filter -MaxEvents 10 | ft logname, timecreated
, message -Wrap
LogName TimeCreated Message
------- ----------- -------
System 2017.03.18. 18:09:41 The operating system is shutting down at syst
em time 2017-03-18T17:09:41.419449800Z.
System 2017.03.18. 18:09:40 The kernel power manager has initiated a shut
down transition.
Shutdown Reason: Kernel API
System 2017.03.18. 18:09:38 WLAN AutoConfig service has successfully stop
ped.
System 2017.03.18. 18:09:36 Bluetooth radio has accepted discoverability
due to policy Bluetooth\AllowDiscoverableMode
.
Security 2017.03.18. 18:09:36 The event logging service has shut down.
System 2017.03.18. 18:09:36 DHCPv4 client service is stopped. ShutDown Fl
ag value is 1
System 2017.03.18. 18:09:36 DHCPv6 client service is stopped. ShutDown Fl
ag value is 1
System 2017.03.18. 18:09:36 The Event log service was stopped.
Application 2017.03.18. 18:09:36 The User Profile Service has stopped.
System 2017.03.18. 18:09:36 The WinRM service is not listening for WS-Man
agement requests.
User Action
If you did not intentionally stop the servic
e, use the following command to see the WinRM
configuration:
winrm enumerate winrm/config/listener
Itt most nem csak egy bejegyzést kértem, hanem 10-et, hogy lássuk azt, hogy a bejegyzések több napolóból érkeztek.
Egy másik lehetőség, hogy ki is hagyhatunk egy részhalmazt a találati listából. Mint ahogy a grafikus felület is írja, negatív EventID-kat használva azok ki lesznek hagyva az eredményből:
117 . ábra A 43-as azonosítójú bejegyzések kihagyása
Nézzük meg ezt XML-ben:
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[Provider[@Name='Microsoft-Windows-WindowsUpdateClient'] and ( (EventID >= 19 and EventID <= 44) )]]</Select>
<Suppress Path="System">*[System[(EventID=43)]]</Suppress>
</Query>
</QueryList>
Látható, hogy egy Suppress tag került be, ahol ugyanolyan feltételeket adhatunk meg, mint a Select részben. A grafikus felület csak az EventID-kra vonatkozóan teszi lehetővé a kizárást, de PowerShellben természetesen akármilyen jellegű kizárást tehetünk. Például az Application Log 1000-es EventID-jű bejegyzéseiből ki szeretném hagyni a LoadPerf forrásból származókat:
118 . ábra A LoadPerf forrásból származó bejegyzéseket szeretném kihagyni
Ez a szűrés így néz ki:
$filterKizár2 = @"
<QueryList>
<Query Id="0"
Path="Application">
<Select
Path="Application">*[System[(EventID=1000)]]</Select>
<Suppress
Path="Application">*[System[Provider[@Name='Microsoft-Windows-LoadPerf']]]</Suppress>
</Query>
</QueryList>
"@
Get-WinEvent -FilterXml $filterKizár2
És az eredmény:
PS C:\> Get-WinEvent -FilterXml $filterKizár2
ProviderName: Application Error
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
2017.03.12. 21:27:15 1000 Error Faulting application na...
2017.03.12. 21:26:59 1000 Error Faulting application na...
2017.03.12. 21:26:04 1000 Error Faulting application na...
...
Ebből a kis ízelítőből is látható, hogy az XML alapú lekérdezések szinte korlátlan lehetőségeket adnak eseménynapló bejegyzések szűrésére, keresésére. Ami még jó ebben, hogy az XML kifejezések vázát összerakhatjuk az Event Viewerben, és a PowerShellben elég finomhangolni.
Láthattuk korábban is, hogy ezeket az új szolgáltatásnaplókat nem az alkalmazásokban, hanem magán a naplón lehet be- és kikapcsolni:
PS C:\> $logName = 'Microsoft-Windows-PrintService/Operational'
PS C:\> Get-WinEvent -ListLog $logName | fl logname, IsEnabled
LogName : Microsoft-Windows-PrintService/Operational
IsEnabled : False
Az IsEnabled tulajdonság mutatja, hogy be van-e kapcsolva az adott naplózás. De sajnos nincs Set‑WinEvent cmdletünk, amivel bekapcsolhatnánk. Ilyenkor megint gondoljunk arra, hogy a .NET keretrendszer objektumaival dolgozunk, így nem árt szétnézni a tagjellemzők között:
PS C:\> $log | gm -Name IsEnabled | fl *
TypeName : System.Diagnostics.Eventing.Reader.EventLogConfiguration
Name : IsEnabled
MemberType : Property
Definition : bool IsEnabled {get;set;}
Például látható, hogy az IsEnabled tulajdonság írható (ott a Definition végén a set). Ez sajnos nem elég, mert az így módosított tulajdonságokat „élesíteni” kell a SaveChanges metódussal:
PS C:\> $log = Get-WinEvent -ListLog $logName
PS C:\> $log.IsEnabled = $true
PS C:\> $log.SaveChanges()
Ezzel már be is kapcsoltuk a nyomtatási feladatok naplózását.