Archiv für den Monat: März 2015

Löschen der Application und Services-Logs

Nach diesem Tipp habe ich eine Weile suchen müssen. Die PowerShell besitzt bekanntlich ein Get-WinEvent-Cmdlet für das Abfragen von Einträgen aus den „Application und Services“-Logdateien (die mit den langen Namen), aber kein Cmdlet, um die Einträge aus einem Protokoll zu löschen. Ein Clear-EventLog funktioniert nicht. Die Lösung ist der Aufruf einer statischen .NET-Methode von einer Klasse, die ich bislang nicht kannte (was generell nichts heißen muss;).

Der folgende Befehl löscht alle Einträge aus dem dem Log „Microsoft-Windows-ManagementOdataService/Operational“:

Index-Eigenschaft bei Select-Object hinzufügen

Manchmal möchte man eine Ausgabe um eine Eigenschaft erweitern, die eine Art „Zählindex“ darstellt und mit jedem Objekt erhöht wird. Eher per Zufall (ein Kursteilnehmer hatte mich auf die Idee gebracht), bin ich auf eine einfache und praktische Lösung gestoßen. Sie basiert auf den eher selten verwendeten OutVariable-Parameter, auf den der Name (ohne $-Zeichen) folgt, in die der Pipeline-Inhalt abgelegt wird

Der folgende Befehl gibt z.B. die Namen aller Prozesse zusammen mit einer Index-Spalte aus:

Mir ist allerdings immer noch nicht klar, warum Select-Object immer die Reihenfolge der Eigenschaften vertauscht.

Datenaustausch zwischen Jobs über Events per Forward-Parameter

Backgorundjobs sind bezüglich ihrer Möglichkeit auf Variablen außerhalb ihres Bereichs zugreifen zu können leider stark eingeschränkt. Da ein Backgroundjob im Rahmen einer eigenen Remoting-Session ausgeführt wird, gelten dieselben Einschränkungen wie allgemein bei PowerShell-Remoting. Soll ein Scriptblock, der als Backgroundjob ausgeführt wird, Mitteilungen an das Skript senden, von dem er aus gestartet wurde, geht dies am einfachsten über Events, konkret die Cmdlets Register-EngineEvent und New-Event. Zuerst wird per Register-EngineEvent ein Event im Scriptblock registriert. Dabei kommt es auf den Forward-Parameter an. Anschließend wird während der weiteren Ausführung des Scriptblocks per New-Event ein Event ausgelöst und automatisch weitergeleitet. Die zu versendenden Daten werden dem MessageData-Parameter übergeben. Außerhalb des Scriptblocks hat man mehrere Möglichkeiten, auf das Event zu reagieren:

  • Man schaut per Get-Event-Cmdlet nach
  • Man wartet auf das Event per Wait-Event-Cmdlet
  • Man registriert es erneut, verbindet es über den Action-Parameter von Register-EngineEvent dieses Mal mit einem Scriptblock, dessen Befehle ausgeführt werden, wenn das Event in der Remote-Session eingetreten ist

Das folgende Beispiel verwendet diese Technik.

Arrays an ein per Powershell.exe gestartetes Skript übergeben

Vor kurzem kam in einer PowerShell-Schulung eine Frage auf, die eigentlich ganz einfach zu lösen sein sollte. Wie kann einem Skript ein Array mit Namen als Argument übergeben werden?

Eigentlich ganz einfach bedeutet, dass dazu lediglich der Parameter als Array deklariert werden muss. Der Ausgangspunkt für das folgende Beispiel ist, dass ein Skript den Status von Diensten, deren Name beim Aufruf übergeben wird, per Get-Service prüfen und in eine Datei schreiben soll. Neben den Namen der Dienste soll daher auch der Pfad einer Datei übergeben werden. Die folgende Parameterdeklaration führt zu dem gewünschten Resultat:

Das Problem: Die Übergabe funktioniert auf einmal nicht mehr, wenn das Skript außerhalb der PowerShell durch den Aufruf von Powershell.exe gestartet wird. Ein

führt nun zu einer Fehlermeldung, die besagt, dass kein Positionsparameter gefunden wurde, der „AudioSrv“ als Argument akzeptiert.

Eine Lösung besteht darin (es gibt sicher noch andere), die selten verwendete Eigenschaft ValueFromRemainingArguments beim Parameter-Attribut zu verwenden:

Damit ist der folgende Aufruf möglich:

Wer genau aufgepasst hat wird festgestellt haben, dass der Dienste-Parameter fehlt. Dies ist die Voraussetzung dafür, dass es funktioniert. Ansonsten ist erneut eine Fehlermeldung die Folge (außerdem muss auf das erste (!) Komma ein Leerzeichen folgen). Wenn ein Skript über die Eingabeaufforderung oder als Verknüpfung aufgerufen wird, kann man damit natürlich leben.