Archiv der Kategorie: Allgemein

PowerShell im Zusammenspiel mit WinForms und WPF – ein umfangreicher Artikel verrät viele Details

Ein PowerShell-Skript mit einer auf WinForms oder WPF basierenden Oberfläche auszustatten ist grundsätzlich nicht schwer und eher eine Fleißarbeit als eine technische Herausforderung sobald man den „Bogen“ raus hat. Wer mehr machen möchte als einen Button und eine TextBox anzuzeigen findet sich aber schnell in den Tiefen des Internets wieder und durchstreift stundenlang einschlägige Fornen.

Per Zufall bin ich auf einen überaus umfangreichen Artikel von einem gewissen Sergueik auf CodePlex gestoßen, in dem der Autor nahezu alle Möglichkeiten beschreibt, die per WinForms und WPF zur Verfügung stehen (ein paar wichtige Themen wie Datenbindung und vor allem wie man es schafft, reaktionsfreudige Oberflächen zu erstellen fehlen soweit ich es beurteilen kann). Der gannze Artikel ähnelt eher einem Buch. Es gibt zudem unzählige Beispiele, die einzeln auf GitHub zur Verfügung stehen. Teilweise wird es etwas zu speziell, da auch viel C#-Code im Spiel ist, und am Ende geht der Autor ausführlich auf das Testen von Web-Anwendungen mit dem Selenium Framework per PowerShell ein, aber insgesamt es ein beeindrucker Überblick, in dem sehr viel Arbeit steckt:

http://www.codeproject.com/Articles/799161/Dealing-with-Powershell-Inputs-via-Basic-Windows-F

PowerShell unter Ubuntu – die ersten Schritte

Seit dem 18. August 2016 heißt die Windows PowerShell ganz einfach nur noch „PowerShell“ und steht als Open Source-Projekt nicht nur für Windows, sondern auch für verschiedene Linux-Distributionen und Mac OS X zur Verfügung (allerdings nicht für iOS, so dass die PowerShell z.B. nicht auf einem iPad installiert werden kann – jedenfalls solange nicht wie sich jemand die Mühe macht .NET Core für iOS zu portieren).

Dabei kommt es wie üblich auf die Feinheiten an. Open Source und damit portabel ist nicht die aktuelle PowerShell 5.0 wie wir sie kennen, die mit der kommenden Version 5.1 offiziell „Desktop Edition heißen wird, sondern eine frühe Alpha-Version einer kommenden Version 6.0. Das bedeutet konkret, dass viele wichtige Funktionen, etwa Cmdlets für WMI- und AD-Abfragen, aktuell noch nicht zur Verfügung stehen. Sie werden kommen, aber das kann noch eine Zeit dauern. Mit anderen Worten, allzu viel anfangen kann man mit der am 18.8 freigegebenen Version im Moment noch nicht.

Dennoch ist alleine der Umstand, dass die PowerShell endlich auch unter Linux läuft faszinierend genug, um es einfach einmal ausprobieren.

Die folgenden Schritte beziehen sich auf Ubuntu 16.04 Desktop:

Schritt 1: Herunterladen der Deb-Datei

Die Downloadadresse für die 0.9 Alpha für Ubuntu 16.04 ist:

https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/powershell_6.0.0-alpha.9-1ubuntu1.16.04.1_amd64.deb

Schritt 2: Installieren
Was macht man mit einer Deb-Datei unter Linux? Zumindestens unter Ubuntu funktioniert der Doppelklick. Das Paket wird damit installiert, was in diesem Fall lediglich bedeutet, dass sein Inhalt in ein eigenes Verzeichnis kopiert und im Verzeichnis usr\bin eine Art Verknüpfung auf die Powershell-Programmdatei angelegt wird.

Die Suche nach dem Begriff "PowershelL" war erfolgreich

Die Suche nach dem Begriff „PowershelL“ war erfolgreich

Schritt 3: PowerShell starten
Wie startet man eine Anwendung unter Ubuntu, wenn man nur Windows kennt? Gute Frage. Ich habe mir so beholfen, dass ich zuerst das Terminal-Programm gestartet habe, dahinter steckt die Bash-Shell, dann auf vertraute Weise per cd in das Verzeichnis \usr\bin navigierte und dann die PowerShell durch Eingabe von „.\powershell“ startete. Die PowerShell startet nicht in einem eigenen Fenster, sondern läuft im aktuellen Terminalfenster.

Unter Ubuntu belegen die meisten Prozesse nur ein paar KB statt über 100MB

Unter Ubuntu belegen die meisten Prozesse nur ein paar KB statt über 100MB

Interessant ist, dass mein „Lieblingsbefehl“ Get-Process | Where WS -gt 50MB keine Ausgabe zur Folge hatte. Wie sich herausstellte, gibt es bei Ubuntu kaum einen Prozess, der mehr als 100KB (!) belegt.

PowerShell unter Ubuntu

PowerShell unter Ubuntu

Wie erwartet funktioniert einiges nicht, z.B. WMI-Abfragen über Get-CIMInstance.

Das Ganze war eher eine Art Schnelldurchlauf. Eine schönere Anleitung gibt es von Sebastian Klenk, technischer Evangelist bei Microsoft – er beschreibt in einem Blog-Eintrag wie sich die PowerShell in einer Ubuntu-VM unter Azure installieren lässt, in dem er sich von seinem Windows 10-PC unter dem neuen Ubuntu Subsystem per SSH mit dem Azure Ubuntu verbindet und über diese Verbindung die PowerShell installiert:

https://blogs.technet.microsoft.com/sebastianklenk/2016/08/19/how-to-powershell-on-linux/

Coole Sache! (aber nicht vergessen: Auch eine Ubuntu-VM kostet bei Azure Geld – Open Source hin oder her;)

PowerShell unter Mac OS X – der Weg ist das Ziel

Warum um alles in der Welt sollte man die PowerShell auf einem Apfel-Computer benötigen? Ein 100% überzeugendes Argument fällt mir dazu zwar nicht ein, aber wenn es diese Option seit kurzem gibt, sollte man sie auch einmal ausprobieren.

Schritt 1:
Der erste Schritt besteht in dem Download der Paketdatei, die das PowerShell-Team im Rahmen des GitHub-Portals auf der Release-Page für die aktuelle Alpha-Version zur Verfügung stellt:

https://github.com/PowerShell/PowerShell/releases/tag/v6.0.0-alpha.9

Schritt 2:
Anklicken der Pkg-Datei mit der rechten Maustaste (die gedrückte Ctrl-Taste ist offenbar nicht erforderlich) und Auswahl von Öffnen. Anschließend das Paket installieren.

Als absoluter Mac-Dummy-User habe ich nach der Standardinstallation das Verzeichnis nicht finden können, unter dem die Dateien abgelegt wurden. Unter „Programme“ wird die PowerShell offenbar nicht angezeigt. Erst als ich das Paket auf eine leere Festplatte „installieren“ ließ, habe ich das Verzeichnis usr/local/microsoft/powershell/6.0.0-alpha.9 mit der Powershell.exe entdeckt;)

Schritt 3:
Ein Doppelkick auf Powershell.exe startet das gute Stück. Bei den ersten Gehversuchen wird schnell deutlich, dass natürlich nicht die gewohnte Funktionalität im vollem Umfang zur Verfügung stehen kann. Was z.B. noch nicht implementiert wurde ist WMI auf der Basis von CIM. Trotzdem ist es beeindruckend, dass ein „Get-Process | WS -gt 50MB“ nun auch unter Mac OS X funktioniert. Auch wenn es im Moment noch keine zwingenden Anwendungsfälle gibt, eine Bereicherung ist die PowerShell in dieser Umgebung, in der bislang das Terminal-Fenster mit der Bash-Shell die einzige (vorinstallierte) Option war, in jedem Fall.

Eine kleine "Sensation" - dank Open Source-PowrerShell gibt es die PowreShell-Konsole nun auch auf dem Mac

Eine kleine „Sensation“ – dank Open Source-PowrerShell gibt es die PowreShell-Konsole nun auch auf dem Mac

Die Pflichtparameter eines Cmdlets auflisten – ein weiteres Beispiel für den PipelineVariable-Parameter

Zur Zeit beschäftige ich mit Azure AD, Office 365 und damit auch mit dem neuen AzureAD-Modul, das aktuell (Stand: Ende Juli 2016) noch als Preview vorliegt (das Modul AzureADPreview wird am einfachsten per Install-Module hinzugefügt). Da die Dokumentation noch „etwas“ spärlich ist, ist es hilfreich bei einem Cmdlet seine Pflichtparameter zu finden.

PowerShell-Commands basieren natürlich ebenfalls auf Objekten, ein Get-Command gibt bei einem Cmdlet ein CmdletInfo, bei einer Function entsprechend ein FunctionInfo-Objekt zurück. Beide besitzen eine Parameters- und eine ParameterSets-Eigenschaft. Das trickreiche ist, dass Parameters ein Objekte vom Typ ParameterMetadata, ParameterSets dagegen Objekte vom Typ CommandParameterInfo liefert. Nur bei diesem Objekt gibt es eine IsMandatory-Eigenschaft.

ParameterSets ist eine sperrige Eigenschaft. Es handelt sich um eine generische Collection (sie kann nur Objekte eines bestimmten Typs aufnehmen, in diesem Fall vom Typ CommandParameterSetInfo im Namespace System.Management.Automation) vom Typ ReadOnlyCollection im Namespace System.Collections.ObjectModel. Die vollständige Typenbezeichnung lautet

System.Collections.ObjectModel.ReadOnlyCollection`1[System.Management.Automation.CommandParameterSetInfo]

Ein CommandParameterSetInfo-Objekt besitzt drei Eigenschaften: Name, IsDefault und Parameters.

Auch hinter Parameters steckt ebenfalls eine ReadOnlyCollection. Sie beherbergt Objekte vom Typ CommandParameterInfo. Wie ein

[System.Management.Automation.CommandParameterInfo].GetProperties().Name

verrät, besitzt ein CommandParameterInfo-Objekt folgende Eigenschaften:

Name
ParameterType
IsMandatory
IsDynamic
Position
ValueFromPipeline
ValueFromPipelineByPropertyName
ValueFromRemainingArguments
HelpMessage
Aliases
Attributes

Also muss ein Befehl, der alle Pflichtparameter eines Command zurückgibt, zuerst die ParameterSets- und danach die Parameters-Eigenschaft durchlaufen.

Die folgende Function gibt zu einem Command, dessen Name beim Aufruf übergeben wird, die Namen der Pflichtparameter aus:

Der Aufruf von

listet die drei Pflichtparameter des Cmdlets auf.

Eine Kleinigkeit fehlt noch. Es wäre ganz nett, wenn auch der Name des Parametersets und eine Angabe darüber, ob es das Defaultparameterset ist, ausgegeben werden würde. Das kleine „Problem“ besteht darin, dass das CommandParameterInfo diese Information nicht mehr enthält. Dank es mit der PowerShell 4.0 eingeführten PipelineVariable-Parameters ist das zum Glück kein Problem.

Die folgende Function gibt zu jedem Pflichtparameter auch den Namen des Parametersets aus:

Wie gut bin ich in PowerShell? Das Very Effective Exam testet Deine Fähigkeiten

Auf dem DevOps and PowerShell Summit 2016, der Anfang April stattfand, gab es wieder die Gelegenheit an einem „Very Effective Exam“ teilzunehmen (den etwas ungewöhnlichen Namen muss sich der Erfinder des Tests, vermutlich Don Jones himself, ausgedacht haben). Der Test ist eine Art „Wie gut kann ich mit der PowerShell umgehen?“-Test und entstand in erster Linie aus dem Umstand einer fehlenden offiziellen Alternative, da sich Microsoft offenbar weigert eine Zertifizierung für die PowerShell einzurichten.

Der Tests bestand dieses Mal darin, dass man ein kleines PowerShell-Skript mit einer Function, in der einfache WMI-Abfragen durchgeführt wurden, und den per Start-Transcript aufgezeichneten Output des Skriptes vorgelegt bekam. Das Skript enthielt ca. 10 Fehler, die dazu führten, dass einzelne Befehle nicht ausgeführt oder so geschrieben waren, dass der angegebene Output nicht hätte resultieren können. Das größte „Rätsel“ (leider auch für mich) war, warum der Aufruf von Get-Help keinen Output produzierte. Für das Finden der Fehler hatte man 60 Minuten Zeit. Hilfsmittel waren keine zugelassen außer einem Blatt Papier und einem Kugelschreiber.

Wenn sich die Aufgabe vielleicht einfach anhören mag, der Test hatte es in sich, denn man musste genau hinschauen, auf Kleinigkeiten achten und vor allem die Feinheiten von Advanced Functions sehr gut kennen, ein wenig über WMI und CIM Bescheid wissen, vor allem aber der Lage sein deduktiv zu arbeiten. Mit anderen Worten: Wenn der Output so aussieht, dann muss das Cmdlet, das diesen Output produziert, mit jenen Parametern und deren Werten aufgerufen werden.

Ich empfand die Aufgabe am Anfang als relativ schwer und vor allem ungewöhnlich aufgrund der Aufgabenstellung, nach einer Weile hatte ich mich etwas daran gewöhnt und etwa eine halbe Stunde später (an dem Tisch, an dem ich saß, schrieben die anderen bereits eifrig – ich kam mir fast vor wie bei einer Klassenarbeit in der Schule oder einer Prüfung an der Fachhochschule) war ich relativ entspannt und hatte das Gefühl fast alles im Griff zu haben. Offenbar eine Selbsttäuschung, denn wie es aussieht habe ich den Test nicht bestanden. Dazu hätte ich mindestens 8 der 10 Fehler finden bzw. die Befehle so ändern müssen, dass das protokollierte Ergebnis herauskam. Der Umstand, dass es nur ca. 20% der ca. 40 Teilnehmer, alle mehr oder weniger erfahrene PowerShell-User, geschafft hatten (also knapp 8) ist in diesem Zusammenhang nur ein kleiner Trost.

Die Lehre aus der Geschichte: Achte auf die Kleinigkeiten und glaube nicht ein Werkzeug verstanden zu haben bis Du es wirklich verstanden hast. Auf der anderen Seite: Es dürfte äußerst selten vorkommen, dass man nur knapp 1 Stunde Zeit hat und in einer künstlichen Stresssituation die Fehler in einem Skript finden und dabei auf jede Kleinigkeit achten muss. Dennoch sind solche Tests eine gute Gelegenheit seine eigene Fähigkeiten einer kritischen Betrachtung zu unterziehen. Allzu oft gibt man sich nach dem Motto „Passt schon“ mit einem Kompromiss zufrieden. Ganz optimal ist diese Einstellung nicht.

Wer sich nun für die Aufgabe interessiert: Don Jones war dieses Mal gnädig und hat die Aufgabe nicht nur veröffentlicht, sondern auch höchstpersönlich die Lösung kommentiert:

http://powershell.org/wp/2016/04/22/verified-effective-exam-results/

PoshWizard – eine kleine DSL für das Erstellen von Assistenten

Angeregt durch PScribo und einen Vortrag von Kirk Munro auf dem letzten DevOps und PowerShell Summit habe ich selber eine kleine Domain Specific Language (DSL) mit dem Namen PoshWizard erstellt, mit deren Hilfe sich relativ einfach Assistenten erstellen lassen, die den Anwender durch eine Folge von Eingaben führen und mit den eingegebenen Werten am Schluss eine Aktion ausführen.

Der folgende Text erzeugt einen Assistenten mit insgesamt fünf Fenstern:

Das Ergebnis ist ein WPF-Fenster mit einem TabControl, das für jeden Schritt ein Register enthält (ursprünglich wollte ich alle übrigen Register bis auf das aktuelle ausblenden, aber in dieser Varianten steht eine zusätzliche Navigationsebene zur Verfügung und sie ist vor allem etwas leichter umzusetzen).

Am Ende müssen die eingegebenen Daten lediglich über Variablen angesprochen werden. Im Grunde also ganz einfach.

EIn per PoshWizard angelegtes Fenster

EIn per PoshWizard angelegtes Fenster

Die ganze DSL steht als Modul unter GitHub zur Verfügung:

https://github.com/pemo11/PoshWizard

Ich bin gespannt, ob jemand das Modul einsetzen wird und freue mich natürlich über ein FeedBack. Ob das Modul „produktionsreif“ ist, kann ich im Moment noch nicht beurteilen, da ich es noch nicht ausgiebig getestet habe (es fehlen außerdem noch Tests, die der Autor von PScribo konsequent für jede Function verwendet). Auch die Optik ist sicherlich noch verbesserungswürdig was die Platzierung der einzelnen Bedienelemente angeht. Außerdem fehlt noch die eine oder andere Funktionalität. Ein Beispiel ist ein Wenn-Befehl, durch den eine im letzten Schritt getroffene Auswahl für die Entscheidung verwendet wird welches Fenster als nächstes angezeigt wird. Insgesamt bin ich mit dem Ergebnis aber sehr zufrieden, vor allem angesichts des Umstandes, dass ich aktuell ledlgich ein paar Stunden in die Umsetzung investiert habe. Ich sehe es in erster Linie als ein Beispiel dafür welches Potential in der PoweShell in diesem Bereich steckt.

Die ersten Schritte mit PScribo

PScribo von Ian Brighton ist eine Art „PowerShell-Reporting-Tool“, auf welches das Attribut genial auch bei nüchterner Betrachtung zutrifft. Warum? Weil es, genau wie Pester, genau das macht was es machen soll und das mit einer verblüffenden Leichtigkeit. Aktuell steht es nur als Zip-Datei unter GitHub zur Verfügung. Dort hat der Autor aber bereits angekündigt, dass es demnächst auch über die PowerShell Gallery zur Verfügung stehen wird und damit per Install-Module PScribo hinzugefügt werden kann.

Hier ein kleines Beispiel, das ein paar Eckdaten eines AD in einem Report zusammenfasst.

Die Idee ist, dass mit Hilfe der Befehle einer Dokumente-DSL (eine Domänenenspezifische Sprache umfasst Befehle, die im Rahmen einer „Problemdomäne“ zur Lösung von Problemen verwendet werden – dahinter stecken bei der PowerShell in der Regel nur Functions) der Aufbau des Dokuments beschrieben wird. Per Section wird z. B. ein neuer Bereich eingeleitet, per PageBreak ein Seitenumbruch und per Paragraph ein neuer Absatz. Die eigentlichen Daten werden per Table ausgeben, auf Wunsch auch als Liste. Eine weitere Stärke von PScribo ist die Leichtigkeit, mit der sich Tabellen formatieren lassen. Zeilenweise und spaltenweise. Das unscheinbare TOC zu Beginn der Dokumentdefinition fügt ein Inhaltsverzeichnis ein, zu dem automatisch alle Sektionen zusammengefasst werden.

Der Aufruf sieht wie folgt aus:

Das Ergebnis sind jeweils eine Docx- und eine Html-Datei im aktuellen Verzeichnis. Das kleine Beispiel kann natürlich nur einen Teil der Möglichkeiten andeuten. Der Autor stellt im Examples-Unterverzeichnis des Modulverzeichnisses mehrere Dutzend Beispeiele zur Verfügung, die keine Fragen mehr offen lassen sollten. DSL haben Potential. Auf dem DevOps und PowerShell Summit 2016 zeigte PowerShell-Exprte Kirk Munro wie DSLs per PowerShell umgesetzt werden. Das Video sollte es in Kürze auf YouTube geben.

Wo bleibt PowerShell 5.0 (bzw. WMF 5.0)?

Das PowerShell-Team macht es äußerst spannend was die offizielle Freigabe der Version 5.0 des Windows Management Framework und damit der PowerShell 5.0 angeht. Nachdem mit Windows 10 bereits (lange ist es her;) im Sommer letzten Jahres eine Vorabversion „offiziell“ wurde, gab es im Dezember letzten Jahres die RTM-Version (Release to Manufacturing – ein netter Anachronismus und eine Art „Hommage“ an die Ära, als Betriebssysteme noch auf Disketten ausgeliefert wurden), die aber kurz danach aufgrund eines kleinen Bugs im Zusammenhang mit der Umgebungsvariablen PSModulePath wieder zurückgezogen werden musste. Seit ein paar Tagen gibt es die RTM-Version wieder, u.a. auch für Windows 7, so dass die Frage zwangsläufig im Raum steht wann es denn die offizielle Version geben wird. Wie es aus einer Antwort zu den Kommentaren des Blog-Eintrags des PowerShell-Teams hervorgeht, soll es Ende März soweit sein:

https://blogs.msdn.microsoft.com/powershell/2016/01/19/windows-management-framework-wmf-4-0-update-now-available-for-windows-server-2012-windows-server-2008-r2-sp1-and-windows-7-sp1/#comments

Insgesamt gibt es WMF 5.0 RTM für 7 verschiedene Windows-Vesionen. Da es naturgemäß daher nicht ganz einfach ist, den für ein bestimmtes Betriebssystem erforderlichen Download zu finden, empfehle ich den sehr hilfreichen Blogeintrag des PowerShell-MVPs Emin Atac:

https://p0w3rsh3ll.wordpress.com/

PowerShell goes Open Source?

Noch ist es nicht offiziell, aber ich kann mir gut vorstellen, dass das PowerShell-Team im Laufe des Jahres den Kern von WMF (Windows Management Framework) im Quellcode unter GitHub freigibt und die PowerShell damit zu einer Open Source-Anwendung wird.

Die Adresse gibt es bereits:

https://github.com/powershell

Aktuell sind dort u.a. alle von Microsoft veröffentlichten DSC-Ressourcen, Module wie PSReadLine, die Open SSH-Portierung und die Sprachspezifikation zu finden. Interessant ist, dass offenbar auch die PowerShell-Dokumentation (endlich) in verschiedene Sprachen übersetzt wird. Die entsprechenden Unterverzeichnisse und damit Projektnamen liegen bereits vor.

Damit keine Missverständnisse entstehen. Ob es eine „Open Source-PowerShell“ jemals geben wird ist aktuell pure Spekulation meinerseits, aber ich denke, dass einiges dafür spricht. Es ist aus meiner Sicht weniger eine Frage des Wollens, sondern eher eine Frage des Könnens bzw. der Organisation. Damit ein Projekt „Open Source“ gehen kann, das nicht von Anfang an quelloffen entwickelt wurde, ist viel Vorbereitunsaufwand erforderlich, so dass dies nicht einfach auf Knopfdruck geschehen kann. Ein Open Source-Projekt bedeutet (natürlich) nicht nur, dass der Quellcode auf GitHub heruntergeladen werden kann, es bedeutet in erster Linie, dass die Community in den Entwicklungsprozess integriert werden kann und Änderungen in Gestalt von „Pull requests“ aus der Community wieder in den Entwicklungsprozess einfließen können. Dazu muss ein interner Prozess etabliert werden, bei dem z.B. sichergestellt ist, dass die Änderungen zuvor getestet wurden. Ähnlich oder identisch jenem Prozess, der bereits für .NET Core, dem Open Source-Kern des .NET Framework, etabliert wurde. Und dieser Prozess bedeutet bei Microsoft, dass sich festangestellte und in der Regel gut bezahlte Mitarbeiter darum kümmern. Es entbehrt daher nicht einer gewissen Ironie, dass die inzwischen zahlreichen Open Source-Projekte auch Microsoft jedes Jahr ein paar Millionen kosten dürften.

Auf alle Fälle ist es eine spannende Entwicklung. Ich kann mir gut vorstellen, dass es anlässlich der Build-Konferenz Ende März oder anlässlich der Ignite-Konferenz im September dieses Jahres entsprechende Ankündigungen geben wird.