{"id":1148,"date":"2018-02-08T14:00:08","date_gmt":"2018-02-08T12:00:08","guid":{"rendered":"http:\/\/blog.langlitz-it.de\/?p=1148"},"modified":"2018-07-19T10:08:03","modified_gmt":"2018-07-19T08:08:03","slug":"event-viewer-durch-powershell-ersetzen","status":"publish","type":"post","link":"https:\/\/www.langlitz-it.de\/?p=1148","title":{"rendered":"Event Viewer durch PowerShell ersetzen &#8211; Get-Eventlog \/ Get-WinEvent"},"content":{"rendered":"<p>Sicher haben Sie sich auch schon h\u00e4ufiger \u00fcber den Windows <em>Event Viewer<\/em> \u00e4rgern m\u00fcssen. Nicht nur, dass dieser bei gro\u00dfen Datenmengen extrem langsam wird, auch die Filterm\u00f6glichkeiten sind doch sehr begrenzt. Wenn sich dies auch ab <em>Windows 2008<\/em> schon merklich gebessert hat.<\/p>\n<p>Eine echte Alternative ist da die Logauswertung \u00fcber die <em>PowerShell<\/em>. Achten Sie bitte darauf, die <em>Powershell<\/em> als Administrator zu starten, da Sie sonst nicht den vollen Zugriff auf alle <em>EventLogs<\/em> haben.<\/p>\n<p>Es gibt mehrere Weg zum Ziel, auf die ich im Folgenden n\u00e4her eingehe. Achten Sie auch immer darauf, dass Events im Log mittlerweile mit dem UTC Zeitstempel erstellt werden. Wenn ich nun Events von einem Remote System auswerte, werden diese automatisch mit ihrem Zeitstempel der Zeitzone des abrufenden System angepasst.<\/p>\n<h2>Get-EventLog<\/h2>\n<p>Sie k\u00f6nnen mit dem <em>cmdLet<\/em> <em>get-eventlog<\/em>\u00a0granular filtern. Auch der Remoteabruf eines Logs ist ohne weiteres m\u00f6glich. Im Folgenden sehen Sie einige Beispiele, denen aber keine Grenzen gesetzt sind.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Beispiel 1:<\/span><\/strong><\/p>\n<p>Wurde ein Server in den letzten 30 Tagen gebootet? Dazu brauchen Sie die <em>EventID 6005<\/em> aus dem <em>System<\/em> <em>EventLog,\u00a0<\/em>die\u00a0vermeldet, dass das <em>EventLog<\/em> gestartet wurde. Dies geschieht immer nach einem <em>Reboot<\/em>.<\/p>\n<pre><em>get-eventlog -Computername \"Server\" -logname system -entrytype information -after (get-date).adddays(-30) |? {$_.EventID -eq 6005} |fl Timegenerated<\/em><\/pre>\n<p>Zur\u00fcck geliefert wird das Datum und die Uhrzeit des Eintrags.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Beispiel 2:<\/span><\/strong><\/p>\n<p>Sie m\u00f6chten wissen, wann zuletzt die Systemzeit eines Remote Servers synchronisiert wurde. Suchen Sie dazu nach der <em>EventID 35<\/em> im <em>SystemLog<\/em><\/p>\n<pre>g<em>et-eventlog -Computername \"Server\" -LogName system -EntryType information -after (get-date).adddays(-100) |? {$_.eventid -eq 35} | fl timeg*,mess*,eve*<\/em><\/pre>\n<p><span style=\"text-decoration: underline;\"><strong>Beispiel 3:<\/strong><\/span><\/p>\n<p>Sie rufen alle Error Meldungen des <em>Application Logs<\/em> der letzten 30 Tage ab<\/p>\n<pre><em>get-eventlog -Computername \"Server\" -logname application -entrytype error -after (get-date).adddays(-30)<\/em><\/pre>\n<p>Damit erhalten Sie nat\u00fcrlich eine Vielzahl von Meldungen, die Sie gar nicht interessieren. Angenommen, eine remote Maschine verursacht auf einem DC diverse Fehler, die Sie aber in Ihrer Auswertung ignorieren m\u00f6chten, dann erreichen Sie das mit folgendem Ausschluss auf dem DC:<\/p>\n<pre><em>get-eventlog -Computername \"DCName\" -logname application -entrytype error -after (get-date).adddays(-30) |? {$_.message -notlike \"Servername\"}<\/em><\/pre>\n<p><span style=\"text-decoration: underline;\"><strong>Kosmetik:<\/strong><\/span><\/p>\n<p>Wenn Sie sich das ganze noch als <em>GridView<\/em> ausgeben lassen und somit auch in der Lage sind, graphisch zu filtern, k\u00f6nnen Sie den <em>Event Viewer<\/em> g\u00e4nzlich vergessen.<\/p>\n<pre><em>get-eventlog -logname application -entrytype information\u00a0-after (get-date).adddays(-30) |out-gridview<\/em><\/pre>\n<p><a href=\"http:\/\/blog.langlitz-it.de\/wp-content\/uploads\/2015\/05\/eventviewer.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1152\" src=\"http:\/\/blog.langlitz-it.de\/wp-content\/uploads\/2015\/05\/eventviewer.jpg\" alt=\"eventviewer\" width=\"802\" height=\"557\" srcset=\"https:\/\/www.langlitz-it.de\/wp-content\/uploads\/2015\/05\/eventviewer.jpg 802w, https:\/\/www.langlitz-it.de\/wp-content\/uploads\/2015\/05\/eventviewer-300x208.jpg 300w\" sizes=\"(max-width: 802px) 100vw, 802px\" \/><\/a><\/p>\n<h2>Get-WinEvent<\/h2>\n<p>Mit <em>Get-WinEvent<\/em> k\u00f6nnen Sie noch weit aus mehr\u00a0Optionen nutzen. Mit dem Parameter &#8211;<em>ComputerName<\/em> ist der Abruf auch remote m\u00f6glich. Ein gro\u00dfer Vorteil ist, dass Sie gleichzeitig mehrere Logs durchsuchen k\u00f6nnen, was so einfach mit <em>Get-EventLog<\/em> nicht m\u00f6glich ist. Die Abfrage \u00fcber <em>Get-WinEvent<\/em> ist zudem wesentlich schneller als <em>Get-EventLog<\/em>. Sie erreichen auch die Windows Logs \u00fcber dieses <em>CMDLet<\/em>.<\/p>\n<p><a href=\"http:\/\/blog.langlitz-it.de\/wp-content\/uploads\/2016\/06\/1-2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1472\" src=\"http:\/\/blog.langlitz-it.de\/wp-content\/uploads\/2016\/06\/1-2.jpg\" alt=\"1\" width=\"662\" height=\"203\" srcset=\"https:\/\/www.langlitz-it.de\/wp-content\/uploads\/2016\/06\/1-2.jpg 662w, https:\/\/www.langlitz-it.de\/wp-content\/uploads\/2016\/06\/1-2-300x92.jpg 300w\" sizes=\"(max-width: 662px) 100vw, 662px\" \/><\/a><\/p>\n<p>Zus\u00e4tzlich l\u00e4sst sich mit diesem <em>CMDLet<\/em> auch ein archiviertes Log auswerten. Dazu dient der Parameter &#8211;<em>Path<\/em>\u00a0unter dem Sie dann den Dateinamen des gespeicherten Logs angeben.<\/p>\n<p>Sie haben mit <em>Get-WinEvent<\/em> im Prinzip keine wirklichen Grenzen mehr bei einer Log Auswertung oder der Suche nach bestimmten Events. Ich gehe hier mal auf zwei Filterm\u00f6glichkeiten n\u00e4her ein. Ja, es gibt noch viel mehr Optionen, aber f\u00fcr mich haben sich die beiden Filter \u00fcber &#8211;<em>FilterHashtable<\/em> und &#8211;<em>FilterXML<\/em> als die n\u00fctzlichsten im t\u00e4glichen Arbeiten heraus kristallisiert.<\/p>\n<h3>F\u00fcr die schnelle Suche: <em>FilterHashtable<\/em><\/h3>\n<p>\u00dcber die <em>Hashtable<\/em>\u00a0Option k\u00f6nnen sie g\u00e4ngige Filter angeben. Diese Option ist nach meinem Geschmack die etwas einfachere und deshalb auch f\u00fcr die schnelle Suche etwas besser geeignet. Wenn Sie z.B. den letzten &#8220;<em>unexpected shutdown<\/em>&#8221; suchen, erreichen Sie dies \u00fcber die Suche der vorher definierten <em>Hashtable<\/em>, in der Sie das <em>Log<\/em> und die <em>EventID<\/em> festlegen.<\/p>\n<pre><em>$Hashtable = @{logname=\"System\";ID=\"6008\"}<\/em>\r\n <em>get-winevent -FilterHashtable $Hashtable -MaxEvents 1<\/em><\/pre>\n<p>Nat\u00fcrlich funktioniert der gleiche Aufruf auch f\u00fcr eine <em>Remote<\/em> Maschine. So k\u00f6nnen Sie relativ fix den letzten &#8220;<em>unexpected shutdown<\/em>&#8221; einer Liste von Computern erfassen.<\/p>\n<pre><em>$Computer = \"Server1\",\"Server2\",\"Server3\"<\/em>\r\n <em>$Hashtable = @{logname=\"System\";ID=\"6008\"}<\/em>\r\n <em>$Computer | % {Get-WinEvent -ComputerName $_ -FilterHashtable $Hashtable -MaxEvents 1}<\/em><\/pre>\n<h3>Noch komfortabler: FilterXML<\/h3>\n<p>\u00dcber die <em>XML<\/em> Filteroption k\u00f6nnen Sie die Suche noch weiter granulieren. Ein einfacher <em>XML<\/em> Filter (alle kritischen Events aus dem <em>SystemLog<\/em>) sieht folgenderma\u00dfen aus:<\/p>\n<p><em>$FilterXml = &#8216;&lt;QueryList&gt;<\/em><br \/>\n<em>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0&lt;Query&gt;<\/em><br \/>\n<em>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0&lt;Select Path=&#8221;System&#8221;&gt;*[System[(Level=1 )]]&lt;\/Select&gt;<\/em><br \/>\n<em>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0&lt;\/Query&gt;<\/em><br \/>\n<em>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0&lt;\/QueryList&gt;&#8217;<\/em><\/p>\n<p>Der Aufruf erfolgt dann mit:<\/p>\n<pre><em>Get-WinEvent -FilterXml $FilterXml<\/em><\/pre>\n<p>\u00dcber &#8220;<em>Level<\/em>&#8221; w\u00e4hlen Sie aus, welche Events Sie erhalten m\u00f6chten:<\/p>\n<pre><em>Level 1 = Critical<\/em>\r\n<em>Level 2 = Error<\/em>\r\n<em>Level 3 = Warning<\/em>\r\n<em>Level 4 = Information<\/em><\/pre>\n<p>Einen Einblick \u00fcber die M\u00f6glichkeiten macht die folgende Suchdefinition deutlich:<\/p>\n<pre>\u00a0$FilterXml = '&lt;QueryList&gt;\r\n                   &lt;Query&gt;\r\n                       &lt;Select Path=\"Application\"&gt;*[System[(Level=1 or Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) &amp;lt;= 3600000]]]&lt;\/Select&gt;\r\n                       &lt;Select Path=\"System\"&gt;*[System[(Level=2) and TimeCreated[timediff(@SystemTime) &amp;lt;= 3600000]]]&lt;\/Select&gt;\r\n                       &lt;Select Path=\"HardwareEvents\"&gt;*[System[(Level=4) and TimeCreated[timediff(@SystemTime) &amp;lt;= 7200000]]]&lt;\/Select&gt;\r\n                   &lt;\/Query&gt;\r\n               &lt;\/QueryList&gt;'<\/pre>\n<p>Im Application Log werden alle <em style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\">Critical<\/em><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\">, <\/span><em style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\">Error<\/em><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\"> und <\/span><em style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\">Warning<\/em><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\"> Events aus der letzten Stunde gesucht. Im <\/span><em style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\">Sytem Log<\/em><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\"> werden alle Error Events aus der letzten Stunde gesucht und im <\/span><em style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\">HardwareEvents Log<\/em><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\"> werden alle <\/span><em style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\">Information<\/em><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;\"> Events der letzten 2 Stunden gesucht.<\/span><\/p>\n<p>Wie Sie sehen, sind die M\u00f6glichkeiten sehr vielf\u00e4ltig. Wildcards k\u00f6nnen leider nicht genutzt werden, das liegt aber im XML Format begr\u00fcndet.<\/p>\n<h3>Und hier noch einige Beispiele:<\/h3>\n<p><strong><span style=\"text-decoration: underline;\">Beispiel 1:<\/span><\/strong><\/p>\n<p>Sie m\u00f6chten die letzten 50\u00a0Events aus den\u00a0Logs\u00a0<em>Application<\/em> und <em>System<\/em>\u00a0sehen.<\/p>\n<pre>Get-WinEvent -LogName appl*,sys* -MaxEvents 50<\/pre>\n<p><strong><span style=\"text-decoration: underline;\">Beispiel 2:<\/span><\/strong><\/p>\n<p>Sie m\u00f6chten alle Fehler der letzten 24 Stunden im <em>System Log<\/em> sehen.<\/p>\n<pre><em>Get-WinEvent -FilterHashtable @{logname=\"system\";level=2;starttime=(get-date).addhours(-24)}<\/em><\/pre>\n<p><strong><span style=\"text-decoration: underline;\">Beispiel 3:<\/span><\/strong><\/p>\n<p>Sie m\u00f6chten aus dem Windows Log\u00a0<em>Microsoft-Windows-Kernel-EventTracing\/Admin<\/em> alle Events mit dem <em>Opcode 14<\/em> sehen. Achten Sie darauf, dass die Abfrage des <em>XML<\/em> Pfades <em>Case Sensitive<\/em> ist!<\/p>\n<pre><em>Get-WinEvent -LogName \"Microsoft-Windows-Kernel-EventTracing\/Admin\" -FilterXPath \"*\/System[Opcode=14]\"<\/em><\/pre>\n<p><span style=\"text-decoration: underline;\"><strong>Beispiel 4:<\/strong><\/span><\/p>\n<p>Sie m\u00f6chten sehen, ob das letzte Windows Backup auf einer Remote Maschine erfolgreich durchgelaufen ist.<\/p>\n<pre><em>Get-WinEvent -ComputerName Computername -FilterHashtable @{logname=\"Microsoft-Windows-Backup\";Id=14} -MaxEvents 1<\/em><\/pre>\n<p><span style=\"text-decoration: underline;\"><strong>Beispiel 5:<\/strong><\/span><\/p>\n<p>Zum Abschluss noch eine Suche, die sehr deutlich macht, dass in Flexibilit\u00e4t und Geschwindigkeit der <em>Event Viewer<\/em> auch nicht ansatzweise mithalten kann.<\/p>\n<p>Zuerst lesen wir alle verf\u00fcgbaren Logs mit Eintr\u00e4gen in eine Variable.<\/p>\n<pre><em>$Logs = Get-WinEvent -ListLog * |? {$_.RecordCount -gt 0}<\/em><\/pre>\n<p>Damit sind auch alle Windows- und Anwendungslogs enthalten.<\/p>\n<p>Nun m\u00f6chten Sie in einem bestimmten Zeitfenster nach Fehlern und Warnungen suchen. Sagen wir zwischen 13:00 Uhr und 13:45 Uhr<\/p>\n<pre>$Start = Get-Date \"13:00\"\r\n$End = Get-Date \"13:45\"\r\n\r\n$Logs | % {Get-WinEvent -ea si -FilterHashtable @{logname=$_.logname;starttime=$start;\r\nendtime=$end;level=2,3}}<\/pre>\n<p>Testen Sie das Beispiel. Sie werden absolut \u00fcberrascht sein, wie schnell das Ergebnis erscheint.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sicher haben Sie sich auch schon h\u00e4ufiger \u00fcber den Windows Event Viewer \u00e4rgern m\u00fcssen. Nicht nur, dass dieser bei gro\u00dfen Datenmengen extrem langsam wird, auch die Filterm\u00f6glichkeiten sind doch sehr begrenzt. Wenn sich dies auch ab Windows 2008 schon merklich &hellip; <a href=\"https:\/\/www.langlitz-it.de\/?p=1148\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[468,490,488,487,489,600,486,599,492,601,485,553,491,549,515],"_links":{"self":[{"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=\/wp\/v2\/posts\/1148"}],"collection":[{"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1148"}],"version-history":[{"count":49,"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=\/wp\/v2\/posts\/1148\/revisions"}],"predecessor-version":[{"id":2319,"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=\/wp\/v2\/posts\/1148\/revisions\/2319"}],"wp:attachment":[{"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.langlitz-it.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}