Archiv für den Monat: Februar 2015

Ein Beispiel für den PipelineVariable-Parameter

Mit der Version 4.0 besitzen alle Cmdlets, die etwas in die Pipeline legen, mit PipelineVariable einen weiteren Common Parameter. Er ist dazu da, den aktuellen Inhalt der Pipeline in einer Variablen abzulegen, so dass das Objekt zu einem späteren Zeitpunkt beim Abarbeiten der Befehlskette zur Verfügung steht.

Das folgende Beispiel zeigt, dass der Parameter tatsächlich sehr praktisch sein kann.

Port-Regeln der Windows Firewall auflisten

Möchte man alle Regeln der Firewall auf einen Blick sehen, die Ports betreffen, ist dies im Rahmen der Benutzeroberfläche leider etwas umständlich. Die erweiterte Windows Firewall bietet lediglich eine Export-/Import-Funktion, mit der sich Regeln exportieren und auf einen anderen Rechner wieder importieren lassen. Eine ideale Gelegenheit für einen PowerShell-Befehl, der auch jene Administratoren überzeugen könnte, die eher der Meinung sind, dass die PowerShell ein Rückschritt in Richtung „EDV-Steinzeit“ ist.

Der folgende Befehl ist gleich in mehrerer Hinsicht interessant:

  • Da eine Regel auch mehrere Ports umfassen kann, werden alle Ports einzeln aufgelistet (daher das Foreach-Object, das ansonsten überflüssig wäre)
  • Die LocalPort-Eigenschaft steht nicht immer für eine Zahl, über [Int]::TryParse wird geprüft, ob der Wert der Eigenschaft eine ganze Zahl ist
  • Der Befehl kommt ohne PipelineVariable-Parameter aus und funktioniert daher auch mit der Version 3.0
  • Der Aufruf von Get-NetFirewallRule ist nur erforderlich, wenn auch der Name der Regel und andere Details zur Verfügung stehen sollen

Hinweis: Get-NetFirewallPortFilter und Get-NetFirewallRule gibt es erst ab Windows Server 2012 und Windows 8

Path-Umgebungsvariable aufräumen

Im Laufe der Zeit kann es passieren, dass die Path-Umgebungsvariable Verzeichnisse enthält, die es nicht mehr gibt. Die folgende Befehlsfolge „räumt“ die Path-Umgebungsvariable auf, in dem nicht vorhandene Verzeichnisse entfernt werden:


Natürlich muss der neue Wert so in der Path-Variablen gespeichert werden, dass er beim nächsten PowerShell-Start zur Verfügung steht. Das erledigt die SetEnvironemtnVariable-Methode der Environment-Klasse:


Ein kleine Besonderheit ist mir bei der Umsetzung aufgefallen: Enthält Path einen leeren Pfad (;;), liefert das Test-Path-Cmdlet einen Fehler vom Typ „Terminating“ und ist damit eines der wenigen Cmdlets, bei denen dies der Fall ist. Dieser Fehler kann bekanntlich nicht per ErrorAction-Parameter unterdrückt werden, sondern muss per trap- oder try-Befehl abgefangen werden.

PowerShell für Visual Studio – die PowerShell Tools for Visual Studio von Adam Driscoll

Seit November letzten stehen die PowerShell Tools for Visual Studio über die Visual Studio Gallery als Erweiterung für VS 2013/2015 in der Version 1.04 zur Verfügung.

Damit erhalten nicht nur Entwickler eine Alternative zur PowerShell ISE, die seit der Version 3.0 nur noch minimal verbessert wurde. Auch wenn noch ein paar kleinere „Glitches“ gibt, hat Adam Driscoll einen Super-Job gemacht. Neben Vorlagen für Projekte und einzelne Dateien (Skriptdateien und Module) gibt es ein interaktives Fenster (REPL) unter Ansicht|Weitere Fenster|PowerShell Debug Interactive als Alternative zur Paketmanager-Konsole.

Besonders beeindruckend finde ich die nahtlose Pester-Integration, so dass sich Tests direkt über den Test-Explorer von Visual Studio ausführen lassen (Voraussetzung ist natürlich, dass das Pester-Modul zuvor hinzugefügt wurde). Bei mir hat das allerdings noch nicht funktioniert, ein Beispiel folgt daher in Kürze.

Auswahl der PowerShell Tools im Rahmen der Visual Studio Gallery

Auswahl der PowerShell Tools im Rahmen der Visual Studio Gallery

Die Tools lassen sich zu Visual Studio 2013/2015 hinzufügen (eventuell funktioniert es auch mit VS 2012). Da Visual Studio 2013 in der Community Edition seit einiger Zeit kostenlos ist, sollten die Tools für jeden PowerShell-Anwender in Frage kommen.

Die PowerShell Tools for Visual Studio bieten Intellisense für Commands

Die PowerShell Tools for Visual Studio bieten Intellisense für Commands

Der Projekt-Explorer bei den PowerShell Tools for Visual Studio

Der Projekt-Explorer bei den PowerShell Tools for Visual Studio

 

Ein kleiner Tipp: Da Visual Studio eine 32-Bit-Anwendung ist, muss die Ausführungsrichtlinie für 32-Bit-Hosts (in einer 32-Bit-PowerShell Konsole) separat gesetzt werden.

Ob und welche Version der PowerShell Tools installiert wurde, erfährt man über den Eintrag „Info über Visual Studio“ im Hilfe-Menü.

Das Hilfefenster zeigt an, welche Version der Tools installiert ist

Das Hilfefenster zeigt an, welche Version der Tools installiert ist

 

Mehr zu den PowerShell Tools für Visual Studio im Blog von Adam Driscoll unter

http://csharpening.net

und auf der Projektseite:

https://visualstudiogallery.msdn.microsoft.com/c9eb3ba8-0c59-4944-9a62-6eee37294597

3 Fragen, die PowerShell-Experten beantworten können sollten

Ich weiß nicht, ob PowerShell-Kenntnisse jemals eine Einstellungsvoraussetzung waren (diese Kenntnisse sind mit Sicherheit eine wichtige Zusatzqualifikation für jeden potentiellen Kandidaten für einen „Admin-Job“), aber sollte PowerShell-Know-how in einem Vorstellungsgespräch jemals ein Thema sein, wären die folgenden 3 Fragen für mich jene Fragen, anhand derer man relativ einfach feststellen kann, ob jemand die PowerShell gut oder nur oberflächlich kennt:

Frage 1: Was ist der Unterschied zwischen den Parametern OutVariable und PipelineVariable?

Frage 2: Welche Benutzer dürfen per PowerShell eine Remoting-Verbindung herstellen?

Frage 3: Wie lässt sich mit einem einzigen (!) Befehl die Anzahl aller Klassen ausgeben, die in der aktuellen PowerShell-Sitzung für New-Object für das Anlegen eines neuen Objekts zur Verfügung stehen?

Die Antwort auf Frage 1 setzt voraus, dass sich der „Kandidat“ bereits mit der aktuellen Version 4.0 und ihren Neuerungen beschäftigt hat. Während der Inhalt der auf OutVariable folgenden Variable für die gesamte Pipeline steht, steht der Inhalt der auf den PipelineLineVariable-Parameter (der erst mit der Version 4.0 dazu kam) folgende Variable für das aktuelle Objekt in der Pipeline.

Die Antwort auf Fage 2: Mitglieder der lokalen Administratorengruppe auf dem Remote-Computer und damit Domänadmins und Mitglieder der mit Windows Server 2012 eingeführten Gruppe der Remote-Verwaltungsbenutzer.

Die Anwtwort auf Frage 3 muss man als Administrtor nicht unbedingt kennen, da sie bereits gewisse Kenntnisse voraussetzt, die im Allgemeinen nur Entwickler besitzen. Dennoch ist der Befehl erstaunlich kurz und dank der mit der Version 3.0 eingeführten verkürzten Schreibweise für den Zugriff auf Arrays auch alles andere als kompliziert:

Welche Cmdlets besitzen welchen Parameter?

Für das Kennenlernen der PowerShell ist es enorm hilfreich jene Cmdlets zu finden, die einen bestimmten Parameter besitzen.

Etwa: Welche Cmdlets besitzen z.B. einen ComputerName-Parameter (und ermöglichen damit irgendeine Form von Remoting), bei welchen Cmdlets ist eine Authentifizierung erforderlich, gibt es Cmdlets, die vielleicht einen Password-Parameter besitzen oder bei welchen Cmdlets gibt es den Parameter SupportEvent? Alle diese Fragen beantwortet die folgende kleine Function, die alle Cmdlets, die den beim Aufruf angegebenen Parameter, besitzen „ausspuckt“:

Ein Aufruf von

macht deutlich, dass es zumindestens unter Windows 7 kein Cmldet gibt, das einen Password-Parameter besitzt.

Die PowerShell-Hilfe per Regex durchsuchen

Ein kleiner Nachteil der PowerShell-Hilfe ist, dass die Suchfunktion etwas flexibler sein könnte. Sehr praktisch ist z.B., dass die Eingabe von

dazu führt, dass alle Cmdlets und about_-Themen ausgegeben werden, in deren Name das Wort „Event“ enthalten ist. Sucht man in diesem Zusammenhang aber die Namen jener Variablen, die in einem Eventhandler eine Rolle spielen (etwa $Event oder $EventArgs) wird es schwieriger, da man dazu wissen muss, dass dies automatische Variablen sind, die im Thema about_automatic_variable beschrieben werden. Aber auch mit dieser Information ist die Anzeige einer Beschreibung dieser Variablen etwas umständlich, da man die Variablen in der Beschreibung sämtlicher Variablen lokalisieren muss.

Auch das Durchsuchen selber besitzt eine Besonderheit, die weniger zart beseitete PowerShell-Anwender schnell zum Aufgeben veranlassen dürfte. Der folgende Befehl gibt scheinbar den gesamten Hilfetext zurück:

Der Grund ist ganz einfach, dass help den gesamten Text als einen String liefert und damit der Treffer dazu führt, dass der gesamte Text zurückgegeben wird. Abhilfe schafft das Out-String-Cmdlet mit seinem Stream-Parameter:

Durch den folgenden Befehl werden nicht nur alle Zeilen ausgegeben, in denen das eine Event-Variable enthalten ist, dank dem praktischen Context-Parameter werden auch die zwei folgenden Zeilen ausgegeben:

Die folgende Function Select-Help durchsucht eine einzelne Hilfedatei nach einem Stichwort und gibt die Zeilen aus, in denen es enthalten ist.

Beim Aufruf muss eine Besonderheit beachtet werden. Damit die Pipeline-Bindung gegen ein Array funktioniert, muss das Array als Ganzes übergeben werden. Dazu wird der gesamte Ausdruck in runde Klammern gesetzt, die mit einem Komma eingeleitet werden:

Auch der folgende Befehl gibt die Beschreibung aller in der angegebenen Hilfedatei enthaltenen Event-Variablen aus:

PowerShell-Konferenz 2015 vom 21. bis 23.4.2015

Das Logo zur PowerShell-Konferenz 2015

Vom 21. bis 23.4.2015 findet in Essen in inzwischen dritte PowerShell Anwenderkonferenz statt, die von PowerShell MVP Tobias Weltner und Holger Schwichternberg (IT-Visions) organisiert wird. Weitere Infos gibt es unter

http://www.powershell.de/powershell/konferenz/

Die Liste der Vortragenden auf der zweitägigen Konferenz ist dieses Mal beeindruckend. Unter anderem kommt mit Bruce Payette,der „Chef-Entwickler“ der PowerShell-Skriptsprache im PowerShell-Team aus Redmond (er war allerdings schon einmal in Deutschland. u.a. auf dem PowerShell Deep Dive, der vor einigen Jahren in Frankfurt a.M. stattfand).

Außerdem werden dabei sein: Aleksandar Nikolic, ein exzellenter PowerShell-Experte, der zudem sehr gute Vorträge hält, Bartosz Bielwaski, ein weiterer PowerShell-MVP und PowerShell Top-Experte aus Polen, Peter Kriegel (u.a. bekannt durch das deutschsprachige PowerShell-Community-Portal), Buch-Autor Ulrich Boddenberg, Jeff Wouters, Thorsten Butz, Holger Voges und Thomas Wiefel. Außerdem natürlich Holger Schwichtenberg und Tobias Weltner. Ich selber halte einen Vortrag zum Thema ODATA.

Mehr PowerShell-Kompentenz lässt sich vermutlich nicht in einem Raum zusammenbringen. Es gibt an beiden Tagen nur einen „Track“, so dass man sich jeden einzelnen Vortrag in Ruhe anhören kann. Wer sein PowerShell-Know how abrunden und erweitern möchte, an einem Austausch mit anderen Power Usern interessiert ist, endlich einmal Bruce Payette oder die PowerShell Community im deutschsprachigen Raum kennenlernen möchte, sollte sich anmelden. Auch Essen ist für mich immer eine Reise wert.

Zitat des Tages in ein Profilskript einbinden

Der „Quote of day“ besitzt eine sehr lange Tradition. Ich erinnere mich noch vage an „meinen“ ersten Großrechner (eine Cyber-176, lange ist es her;), bei dem nach jedem Login am Terminal ein mehr oder weniger geistreicher Spruch in grüner Schrift auf schwarzem Hintergrund erschien. Leider ist diese nette Tradition inzwischen nahezu komplett verloren gegangen.

Sog. Quote-Server, die entsprechende Zitate zur Verfügung stellen, gibt es aber immer noch. Sie basieren auf einem sehr einfachen Internet-Protokoll, das über TCP-Port 17 angesprochen wird.

Ich habe eine kleine PowerShell-Function zusammengestellt, die per .NET-Klassen über eine Socket-Verbindung einen öffentlichen Quote Server konnektiert und den Spruch des Tages herunterlädt und anzeigt.

Die Function bietet intern mehrere Quote Server-Adressen an, der Einfachheit halber wird die letzte zugewiesene Adresse verwendet. Aufgerufen wird die Function durch Eingabe des Function-Namens. Soll nach jedem PowerShell-Start ein Zitag angezeigt werden, müssen Function und ihr Aufruf in das Profikskript, z.B. Profile.ps1, eingefügt werden (theoretisch genügt es auch, den Inhalt der Function einzufügen, wenngleich diese Variante natürlich nicht ganz so „schön“ ist).

Der Nachteil dieser kleinen Spielerei liegt natürlich auf der Hand: Jeder Start der PowerShell dauert dadurch ein paar Sekunden länger (mir persönlich macht diese kurze Verzögerung nichts aus, ich freue mich vielmehr über diesen kleinen Ausflug in die goldene Mainframe-Ära).