Az új alkalmazás- és szolgáltatásnaplók kezelése (Get-WinEvent)

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.

Fejlett eseménynapló lekérdezések XML-lel

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&lt;='$($logdate)Z']]]</Select>

        </Query>

        <Query Id="1" Path="System">            <Select>*[System[TimeCreated[@SystemTime&lt;='$($logdate)Z']]]</Select>

        </Query>

        <Query Id="2" Path="Security">            <Select>*[System[TimeCreated[@SystemTime&lt;='$($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 &lt;-t, a > helyett &gt;-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 &gt;= 19 and EventID &lt;= 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.

Szolgáltatásnaplók bekapcsolása

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.



Word To HTML Converter