Geht es oder geht es nicht? Pipeline-Parameter-Bindung mit einem ScriptBlock-Parameter (Geheimnisvolle PowerShell – Teil 3)

Am Anfang nimmt man es als selbstverständlich hin, dass z.B. ein Get-Process Calc | Stop-Process alle laufenden Rechner-Prozesse beendet (sofern einer läuft). Dass dieser Befehl funktioniert liegt ganz einfach daran, dass sowohl der ID-als auch der Name-Parameter von Stop-Process in der Lage sind, ihren Wert von einem Objekt und dessen Eigenschaft zu holen, dass sich in der Pipeline befindet – dieses Prinzip wird allgemein Parameterbindung und in diesem Fall speziell Parameter-Pipeline-Bindung genannt. Ob ein Parameter dieses Pipeline-Bindung bietet, erfährt man z.B. über ein Get-Help <Command> -Parameter <Parametername>.

Manche Cmdlet-Parameter bieten keine Parameter-Pipeline-Bindung. Ein Beispiel ist der Computername-Parameter von Get-WmiObject. Ein

„Server1“, „Server2“, „Server3“ | Get-WmiObject Win32_OperatingSystem

funktioniert daher nicht, was ein wenig schade ist.

Soweit, so gut. Nun hat kein geringer als „PowerShell-Boss“ Jeffrey Snover vor langer Zeit in einem interessanten und wie immer lesenswerten Blog-Eintrag beschrieben wie es doch gehen könnte: In dem der Pipeline-Wert über einen ScriptBlock-Parameter gebunden wird. In etwa so:

„Server1“, „Server2“, „Server3“ | Get-WmiObject Win32_OperatingSystem -Computername { $_ }

Theoretisch sollte das Cmdlet für jeden Server ausgeführt werden, dessen Name sich in der Pipeline befindet. Das Problem: Es funktioniert leider nicht – zumindestens bei mir nicht (und ich habe „einen halben Tag“ die verschiedensten Varianten ausprobiert und sogar ein kleines Cmdlet programmiert, das einen Parameter besitzt, bei dem ich die Attribute ValueFromPipeline und ValueFromPipelineByPropertyName ein Mal auf True (damit funktioniert es) und einmal auf False (damit funktioniert es nicht) gesetzt hatte). Es funktionierte weder in der 1.0-Version, noch der 2.0 CTP V3 noch mit jener 2.0-Version, die Teil von Windows 7 RC1 ist. Eine Frage in der PowerShell-Newsgroup brachte ebenfalls kein Resultat – die einen meinen, es muss gehen, die anderen sind sich nicht ganz sicher. Es gibt natürlich wichtigere Themen, zumal es auch komfortablere Lösungen gibt als die Pipeline per Foreach-Object zu durchlaufen, etwa über eine Pipeline-Funktion:

function Check-AllServer

{  { process { gwmi -class Win32_OperatingSystem -Computer $_ } }

„Server1“, „Server2“, „Server3“ | Check-AllServer

Mich würde aber trotzdem interessieren, ob das von Jeffrey Snover in seinem Blog-Eintrag vorgeschlagene Verfahren funktioniert, da sich so generell jeder Parameter an einen Pipeline-Wert binden ließe, was nicht nur sehr praktisch wäre, sondern auch ein weiterer Beleg für die vielgepriesene Konsistenz der PowerShell wäre. Vielleicht jemand eine Idee?

Advertisements

Kommentar verfassen

Bitte logge dich mit einer dieser Methoden ein, um deinen Kommentar zu veröffentlichen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s