Tags: PowerShell, Log-Management
Sowohl Windows als auch die meisten Anwendungen schreiben laufend Informationen in Log-Dateien, die besonders für das Troubleshooting hilfreich sein können - vorausgesetzt, man findet die entscheidenden Einträge. PowerShell bietet für diese Aufgabe gleich zwei Cmdlets, nämlich Get-EventLog und Get-WinEvent.
Die einfachste Möglichkeit, Einträge in den Logdateien von Windows zu filtern, stellen die so genannten benutzerdefinierten Ansichten in der Ereignisanzeige dar. Dort kann man mit Hilfe einer Abfragemaske die gewünschten Kriterien für einen Filter auswählen.
Zusätzliche Filteroptionen durch PowerShell
Zu den Einschränkungen dieses Tools gehört jedoch, dass es keine Volltextsuche in den Meldungen zulässt. Außerdem kann man mit der Ergebnisliste nicht viel mehr tun als durch die Einträge zu scrollen und zu hoffen, dass man dort die gesuchten Hinweise auf die Ursache von Problemen findet.
Dagegen können die Cmdlets Get-EventLog und Get-WinEvent, die PowerShell für diesen Zweck bereitstellt, die Events auch anhand der Meldungstexte filtern und das Ergebnis über beliebige weitere Kommandos nachbearbeiten.
Es stellt sich natürlich die Frage, wieso PowerShell für eine Aufgabe gleich zwei Cmdlets mit einem ähnlichen Funktionsumfang bietet. Das hat in erster Linie historische Gründe, nachdem Get-EventLog bereits seit der Version 2.0 an Bord ist, während Get-WinEvent erst mit Windows 8 hinzukam.
Außerdem verfolgen sie jeweils verschiedene Ansätze, weil das einfacher zu nutzende Get-EventLog für jedes Filterkriterium einen eigenen Parameter vorsieht, wogegen Get-WinEvent diese in Form eines Hashtable oder einer XML- bzw. XPath-Abfrage entgegennimmt. Das neuere Get-WinEvent ist zusätzlich in der Lage, auch archivierte Logfiles zu untersuchen.
Beiden gemeinsam ist jedoch, dass sie über den Parameter ComputerName auch die Logfiles (mehrerer) entfernter Rechner auslesen können.
Get-EventLog
Eine typische Abfrage mit Get-EventLog, die Ereignisse auf einen bestimmten Zeitraum und einen bestimmte Typ (Warnung, Fehler, etc.) eingrenzt, könnte so aussehen:
Get-EventLog -LogName System -after 01.07.2015 -before 20.07.2015 -EntryType Error
Eine Einschränkung dieses Cmdlets besteht darin, dass es für den erforderlichen Parameter LogName nur einen einzelnen Wert akzeptiert, man also mit einem Aufruf immer nur ein Protokoll untersuchen kann.
Möchte man zum Beispiel die Einträge aller Eventlogs analysieren, dann könnte man vorhandenen Logfiles mit Hilfe des Parameters -List ermitteln und über eine Pipe an einen zweiten Aufruf von Get-EventLog weiterleiten:
Get-EventLog -List | %{Get-EventLog -LogName $_.log -after 08.07.2015 -EntryType Error}
Das % ist ein Alias für Foreach-Object, das wir benötigen, um den Namen jedes Eventlogs einzeln an Get-EventLog zu übergeben.
Ein gängiges Filterkriterium für Ereignisse ist ihre ID, die man über den Parameter -InstanceID abfragen kann, weil dieser in der Regel identisch mit der EventID ist und für die es keinen Parameter gibt.. Er akzeptiert auch mehrere Werte, die man durch Komma voneinander trennen muss:
Get-EventLog -LogName System -after 01.07.2015 -InstanceId 1501,10010
Wie bereits erwähnt, ist PowerShell im Unterschied zur Ereignisanzeige in der Lage, auch den Meldungstext zu durchsuchen.
Allerdings beherrscht Get-EventLog keine einfache Substring-Suche, so dass man immer Wildcards verwenden muss, wenn man nicht den vollständigen Text eingeben möchte:
Get-EventLog -LogName system -Message "*Gruppenrichtlinien*" -after 20.07.2015|select EventID, TimeGenerated, Message | fl
Dieses Beispiel extrahiert alle Ereignisse nach dem 20.7.2015, deren Nachricht die Zeichenkette "Gruppenrichtlinien" enthält und zeigt für jedes in Listenform die ID, das Datum inklusive Uhrzeit sowie die Meldung an.
Get-WinEvent
Alle obigen Beispiele lassen sich auch mit Get-WinEvent formulieren, und darüber hinaus bietet es noch weitere Möglichkeiten. Allerdings folgt es einem anderen, nicht gerade einfacheren Ansatz.
Etwas unübersichtlich wird seine Verwendung dadurch, dass bestimmte Parameter nur in Kombination mit anderen zulässig sind. So eignet sich LogName, das im Gegensatz zu Get-EventLog auch mehrere Werte zulässt, nur für den Einsatz zusammen mit einer XPath-Abfrage, die einzelne Elemente in der XML-Darstellung des Events auslesen kann.
Diese relativ einfache Repräsentation, die weitgehend mit Elementen ohne Attribute auskommt, kann man in der Ereignisanzeige studieren. Das ist allerdings notwendig, weil seine Struktur nicht einheitlich ist und sich je nach Provider und EventID ändern kann.
Folgendes Beispiel würde alle Einträge in den Protokollen System und Anwendung ermitteln, die der SID eines bestimmten Users zugeordnet sind:
Get-WinEvent -LogName Application, System -FilterXPath "*/System[Security/@UserID='S-1-5-20']"
Wenn man in diesem Aufruf den Parameter LogName durch Path ersetzt, dann kann man auf diese Weise archivierte Logfiles untersuchen.
Die häufiger verwendete Methode dürfte darin bestehen, mehrere Kriterien in Form eines Hashtable an das Cmdlet zu übergeben. Dieser enthält dann auch den Namen des Protokolls, wobei bei dieser Art des Aufrufs nur mehr ein einziges angegeben werden kann:
Get-WinEvent -FilterHashtable @{logname="system";level=3;StartTime="01.07.2015";}
Dieser Befehl würde alle Einträge aus dem Protokoll System liefern, die seit dem 1.7.2015 geschrieben wurden und den Status Warnung haben.
Get-WinEvent ist selbst nicht in der Lage, die Textnachricht des Events zu durchsuchen. Vielmehr muss man zu diesem Zweck das Ergebnis einer Abfrage an ein Where-Object weiterleiten und dort über einen entsprechenden Vergleich filtern:
(Get-WinEvent -ListProvider *Hyper*).Events | where Description -like "*RemoteFX*"
In diesem Beispiel würden alle Einträge, die von einem der Provider für Hyper-V geschrieben wurden, nach der Zeichenkette "RemoteFX" durchsucht.
Täglich Know-how für IT-Pros mit unserem Newsletter
Verwandte Beiträge
- Log-Einträge und Dateien verschlüsseln mit PowerShell und GPO
- Deep Scriptblock Logging: PowerShell-Kommandos im Eventlog aufzeichnen
- PowerShell-Logging: Befehle in Transcript-Datei aufzeichnen
- Nachfolger für Windows PowerShell: PowerShell 7 bringt Log-Forwarding, Credential-Store, Long Term Servicing
- PowerShell für Logon-Scripts verwenden
Weitere Links