14 min read
Der Schlüssel zu produktiver Softwareverwaltung: winget & PowerShell
Steigere die IT-Effizienz mit Winget und PowerShell! Lies, wie du Installationen, Updates und die Verwaltung von...
ScriptRunner Blog
Erweitere PowerShell mit .NET für eine leistungsstarke Ereignisautomatisierung. Systemereignisse wie ein Profi überwachen und verarbeiten! Der Artikel beantwortet die Frage, wie du .NET-Klassen nutzen kannst, um Ereignisse zu überwachen und automatisierte Antworten auszulösen und so die Möglichkeiten der PowerShell für eine effiziente Systemverwaltung zu erweitern.
Das Oxford-Wörterbuch definiert ein Ereignis als "eine Sache, die passiert, besonders etwas Wichtiges". In der Computerwelt assoziieren die meisten Menschen Ereignisse mit der Protokollierung, aber Ereignisse gehen darüber hinaus. Tatsächlich ist ein Protokoll nichts anderes als eine Ausgabe eines Ereignisses.
Dieser Blogbeitrag behandelt zwei Arten von Ereignissen, PowerShell Engine Events und .NET Object Events (klickehier für den zweiten Teil, Meistere PowerShell WMI: überwache automatisiert System-Events).
Wir schauen uns an, wie wir sowohl mit PowerShell-Engine-Ereignissen als auch mit .NET-Objekt-Ereignissen umgehen können und welche PowerShell-Befehle dabei helfen.
Bevor wir uns in die Details von PowerShell-Ereignissen vertiefen, müssen wir zunächst Klassen und Objekte verstehen.
Einfach, oder? Vereinfachen wir dies anhand eines realen Beispiels.
Ich bin ein Objekt der Klasse meiner Eltern. Meine Eltern haben bestimmte Eigenschaften wie schwarze Haare, braune Augen usw. und bestimmte Methoden wie Kochen, Tanzen usw.
Ein einfaches Beispiel für eine in PowerShell definierte Klasse:
#Definiere eine Klasse
class PrintName {
#Property
[Int] $count
#Funktion
[Void] WriteHello([String] $Name){
Write-Host "Hello $Name"
}
}
#Instantiiere ein Objekts
$Obj = [PrintName]::new()
#Wert für die Eigenschaft count zuweisen
$Obj.count = 1
Write-Host "Property Value" $Obj.count
#Aufruf der Methode GetProcessPath
$Obj.WriteHello('Sonny')
"`n"
Das liefert folgende Ausgabe:
Property Value 1
Hallo Sonny
Im obigen Beispiel haben wir eine Klasse namens "PrintName" mit einer Eigenschaft namens "count" und einer Methode namens "WriteHello" erstellt. Aber warum reden wir über Klassen?
Nun, um Ereignisse zu verstehen, müssen wir zuerst die Klassenstruktur verstehen, denn ein Ereignis ist nichts anderes als eine spezielle Art von Methode.
Speziell, weil andere Teile des Codes Ereignisse abonnieren können (dies ist auch als Ereignisabonnement/event subscription bekannt).
Um andere Programme über bestimmte Aktionen oder Zustandsänderungen eines bestimmten Programms zu informieren, müssen wir Ereignisse in diesem Programm erstellen.
Auf diese Weise können andere Programme diese Ereignisse abonnieren und werden informiert, wenn bestimmte Aktionen oder Zustandsänderungen in Ihrem Programm stattfinden (keine Sorge, wenn wir über .NET Framework-Ereignisse sprechen, werden die Dinge klarer).
PowerShell bietet verschiedene Cmdlets für die Arbeit mit Ereignissen. Beginnen wir mit dem Cmdlet New-Event, das, wie der Name schon sagt, ein neues Ereignis erstellt.
PowerShell bietet verschiedene Cmdlets für die Arbeit mit Ereignissen. Beginnen wir mit dem New-Event cmdlet, das, wie der Name schon sagt, ein neues Ereignis erzeugt.
New-Event
[-SourceIdentifier]
[[-Sender]]
[[-EventArguments]<psobject[]>]
[[-MessageData]]
[
Das New-Event cmdlet erstellt ein neues PowerShell-Ereignis
Wenn ein Ereignis erstellt ist, wird es zum Ereignis-Warteschlange hinzugefügt. Um die Ereignis-Warteschlange anzuzeigen, verwenden wir die Get-Event cmdlet. Wir können unten sehen, dass es zwei Ereignisse in der Warteschlange gibt.
Get-Event
[[-SourceIdentifier]]
[]
Get-Event
[-EventIdentifier]
[]
Die Get-Event Cmdlet ruft Ereignisse in der PowerShell-Ereigniswarteschlange für die aktuelle Sitzung ab
Wie entfernen wir nun Ereignisse aus der Warteschlange? Wir verwenden die Remove-Event cmdlet wie unten gezeigt:
Remove-Event
[-SourceIdentifier]
[-WhatIf]
[-Confirm]
[]
Remove-Event
[-EventIdentifier]
[-WhatIf]
[-Confirm]
[]
Das Remove-Event Cmdlet löscht Ereignisse aus der Ereigniswarteschlange der aktuellen Sitzung
Wie wir sehen können, haben wir nur noch ein Ereignis in der Ereigniswarteschlange.
Bevor wir weitermachen, leeren wir die Ereigniswarteschlange, indem wir das folgende Cmdlet ausführen
Remove-Event -SourceIdentifier *
Zu diesem Zeitpunkt befinden sich keine Ereignisse in unserer Ereigniswarteschlange.
Ereignisse sind nur dann nützlich, wenn jemand sie abonniert hat. Um ein Ereignis zu abonnieren, verwenden wir die Register-EngineEvent cmdlet wie unten gezeigt. Genau wie die Ereignisse, Ereignisabonnement zu der Sitzung hinzugefügt wird.
Um die aktuellen Abonnements in einer Sitzung anzuzeigen, verwenden wir das Cmdlet Get-EventSubscriber. Sowohl Register-EngineEvent als auch das Cmdlet Get-EventSubscriber werden hier gezeigt.
Register-EngineEvent
[-SourceIdentifier]
[[-Action]]
[-MessageData ]
[-SupportEvent]
[-Forward]
[-MaxTriggerCount]
[]
Get-EventSubscriber
[[-SourceIdentifier]]
[-Force]
[]
Get-EventSubscriber
[-SubscriptionId]
[-Force]
[]
Mit Hilfe des Cmdlets Register-EngingeEvent abonnieren wir das Ereignis "MyEvent"
Im obigen Beispiel erstellen wir ein neues Abonnement für ein Ereignis namens "MyEvent". Wir lösen nun das Ereignis mit dem Namen "MeinEreignis" aus.
Wie wir jetzt sehen können, wird, wenn wir das Ereignis "MyEvent" auslösen, der Ereignisabonnent aufgerufen und führt den Aktions-Skriptblock aus.
Der Aktionsblock wird ausgeführt, wenn ein neues Ereignis namens "MyEvent" aufgerufen wird
Um das Abonnement aus der aktuellen Sitzung zu entfernen, verwenden wir das Unregister-Event cmdlet:
Unregister-Event
[-SourceIdentifier]
[-Force]
[-WhatIf]
[-Confirm]
[]
Unregister-Event
[-SubscriptionId]
[-Force]
[-WhatIf]
[-Confirm]
[]
Aufheben der Registrierung des Ereignisabonnenten
Bislang haben wir PowerShell-Engine-Ereignisse besprochen. Wechseln wir nun den Fokus auf .NET Framework-Ereignisse. Eine vollständige Referenz für .NET finden sich unter .NET API browser.
Beginnen wir mit einem einfachen Beispiel der Klasse Process, die Teil des System.Diagnostic-Namensraumes ist.
Wie wir sehen, hat die Klasse Process einen Constructor, Properties, Methods und Events. Zusammen werden sie auch als Klassenmitglieder bezeichnet. Die Klasse Process hat auch drei Ereignisse:
Um auf Klassenmitglieder zugreifen zu können, müssen wir entweder ein neues Objekt instanziieren oder vorhandene Objekte verwenden. Sobald wir ein Objekt haben, können wir es verwenden, um die Ereignisse zu abonnieren.
Beendetes Ereignis für System.Diagnostic.Process Klasse in .NET
PowerShell bietet das Cmdlet "Register-ObjectEvent" zum Abonnieren von .NET-Framework-Ereignissen.
Angenommen, wir möchten das Ereignis "exiting" der Klasse Process abonnieren. Dazu benötigen wir zunächst ein Objekt der Klasse Process. Mit diesem Objekt können wir dann die Member-Ereignisse der Process-Klasse abonnieren.
Das Ereignis exiting wird aufgerufen, wenn ein Prozess beendet wird. In unserem Beispiel werden wir das Objekt calculator process verwenden, um das Ereignis exiting zu abonnieren.
Jeder unter Windows laufende Prozess ist ein Objekt. Um eine Liste der Prozessobjekte unter Windows zu erhalten, können wir die Get-CimInstance cmdlet. Wir sehen, Get-CimInstance gibt die Objekte zurück und kombiniert mit dem Get-Member Cmdlet können wir die Klassenmitglieder anzeigen:
Get-CimInstance
[-ClassName]
[-ComputerName <string[]>]
[-KeyOnly]
[-Namespace]
[-OperationTimeoutSec ]
[-QueryDialect ]
[-Shallow ]
[-Filter ]
[-Property <string[]>]
[]
Verwendung von Get-CimInstance Cmdlet zum Anzeigen laufender Prozesse
Für unser Beispiel starten wir in unserem Code den Taschenrechnerprozess. Wir haben immer die Möglichkeit, ein bereits vorhandenes Prozessobjekt zu verwenden. Im folgenden Code starten wir zunächst den Taschenrechnerprozess und erfassen das Objekt in der Variablen $CalcProcessObj.
$CalcProcessObj = [System.Diagnostics.Process]::Start("calc.exe") Register-ObjectEvent -InputObject
$CalcProcessObj -EventName Exited -Action { cmd.exe /c ping -n 2 8.8.8.8 }
Als Nächstes verwenden wir das Cmdlet Register-ObjectEvent, um das Ereignis "Exited" für den Rechnerprozess zu abonnieren.
Register-ObjectEvent
[-InputObject]
[-EventName]
[[-SourceIdentifier]]
[[-Action]]
[-MessageData]
[-SupportEvent]
[-Forward]
[-MaxTriggerCount]
[]
Wenn der Taschenrechnerprozess beendet wird, wird unser Aktionsblock ausgeführt. Der Aktionsblock enthält einen einfachen Befehl zum Senden von 2 Pings an die IP-Adresse 8.8.8.8.
Das ist die Ausgabe, dass wir das Ereignis erfolgreich abonniert haben:
Ausgabe nach der Ausführung des Cmdlets Register-ObjectEvent
Nachdem wir den Berechnungsprozess beendet haben, können wir sehen, dass der Action Script-Block ausgeführt wurde und dazu führte, dass 2 Pings an die IP-Adresse 8.8.8.8
gesendet wurdenWireshark zeigt 2 Pings, die an die IP-Adresse 8.8.8.8 gesendet wurden
Wie wir bereits gesehen haben, können wir das Cmdlet Get-EventSubscriber verwenden, um eine Liste aller Ereignisabonnements zu erhalten.
Die Ausgabe in unserem Beispiel ist hier zu sehen:
Abrufen einer Liste von Ereignisabonnenten für die aktuelle Sitzung mit Get-EventSubscriber cmdlet
Ahnlich können wir das Cmdlet Unregister-Event verwenden, um die Registrierung eines Ereignisabonnements aufzuheben (ist die Verb-Nomen-Darstellung von Cmdlets nicht toll 😊), wie hier zu sehen ist:
Aufheben der Registrierung eines Ereignisteilnehmers mit dem Cmdlet Unregister-Event
Nehmen wir ein weiteres Beispiel für die FileSystemWatcher-Klasse mit einigen interessanten Events, die wir abonnieren können, wie z. B. die Erstellung oder Löschung von Dateien oder Verzeichnissen.
Angenommen, wir wollen das Erstellungsereignis von Dateien/Verzeichnissen abonnieren.
Wir folgen denselben Schritten wie in unserem letzten Beispiel:
Ereignisse für FileSystemWatcher Klasse in .NET
Erzeugen wir zunächst ein Objekt der FileSystemWatcher-Klasse
$testobj1 = New-Object -TypeName System.IO.FileSystemWatcher
Als Nächstes geben wir unserem Objekt den Verzeichnispfad, den es auf die Erstellung von Dateien/Verzeichnissen überwachen soll
$testobj1.Path = "C:\Users\Public"
Zu guter Letzt verwenden wir das Cmdlet Register-ObjectEvent, um das Ereignis zu abonnieren.
Register-ObjectEvent -InputObject $testobj1 -EventName Created -Action { cmd.exe /c ping -n 2 8.8.8.8 }
Hier ein weiteres Beispiel: die System.Diagnostics.EventLog-Klasse stellt ein Ereignis namens "EntryWritten" bereit, das ausgelöst wird, wenn ein Protokolleintrag geschrieben wird.
Wir folgen den gleichen Schritten wie zuvor: Wir instanziieren ein Objekt, setzen die Log-Eigenschaft für das Objekt (= welches Log wir beobachten wollen) und verwenden dann das Cmdlet Register-ObjectEvent, um das Ereignis EntryWritten zu abonnieren.
$testobj1 = New-Object -TypeName System.Diagnostics.EventLog
$testobj1.Log = "Security"
Register-ObjectEvent -InputObject $testobj1 -EventName EntryWritten -Action { Write-Host "Meow" }
Es ist zu beachten, dass dieser Code die Rechte eines Administrators erfordert, da wir mit der Protokollierung arbeiten.
EntryWritten-Ereignis für die EventLog-Klasse
Für diese Demonstration habe ich von VS Code zu ISE gewechselt. Wir haben das EntryWritten Event für Security Logs abonniert. Unsere Aktionsblöcke schreiben jedes Mal, wenn das Ereignis aufgerufen wird, "Meow".
Abonnement für das Ereignis "EintragGeschrieben"
Es gibt ein paar Dinge, die wir im Auge behalten müssen:
Meistere PowerShell WMI: überwache automatisiert System-Events ist der zweite Artikel zu diesem Thema.
Entfessele das volle Potenzial von PowerShell mit unserem praktischen Poster. Egal, ob frischer Einsteiger oder erfahrener Profi, dieser Spickzettel ist so konzipiert, dass du schnell die wichtigsten und am häufigsten verwendeten Cmdlets findest.
Das Poster ist zum Download und in Papierform erhältlich.
Dez 19, 2024 by Jeffery Hicks
Steigere die IT-Effizienz mit Winget und PowerShell! Lies, wie du Installationen, Updates und die Verwaltung von...
Dez 19, 2024 by Damian Scoles
Mit Microsoft Purview verstehst und verwaltest du Daten in deinem gesamten Datenbestand – wie kannst du PowerShell...
Dez 17, 2024 by Sonny Jamwal
Erweitere PowerShell mit .NET für eine leistungsstarke Ereignisautomatisierung. Systemereignisse wie ein Profi...
Sonny ist ein selbsternannter PowerShell-Prediger, der in der schönen Stadt Halifax an der Ostküste Kanadas lebt. Sonny arbeitet seit mehr als 10 Jahren im Bereich Cybersecurity und hat als primärer technischer Leiter und Fachexperte bei vielen Cyber Security Assessments für verschiedene private und öffentliche Organisationen fungiert. Sonny spricht regelmäßig auf verschiedenen Sicherheitskonferenzen wie BSides, AtlSecCon, ISACA, OWASP etc.