Oktober 2016

Band 31, Nummer 10

Dieser Artikel wurde maschinell übersetzt.

.NET-Grundlagen: Windows PowerShell wird immer besser

Von Mark Michaelis | Oktober 2016

Mark MichaelisIn meinen letzten Artikeln lag der Schwerpunkt auf .NET Core, doch in diesem Monat beschäftigt sich die Kolumne „.NET-Grundlagen“ mit zahlreichen neuen Features, die die Leistungsfähigkeit von PowerShell erheblich steigern. Für mich liegen die wichtigsten Verbesserungen im Bereich der plattformübergreifenden Unterstützung: PowerShell kann nun wirklich unter Linux ausgeführt werden. Darüber hinaus ist GitHub (github.com/PowerShell/PowerShell) nun Open Source, und die ganze Community kann sich an der Optimierung von Features beteiligen. Cool.

Doch die aktuellen Ankündigungen verraten noch nicht die ganze Wahrheit. Als PowerShell 5.0 im Februar veröffentlicht wurde, waren neue oder optimierte Funktionen für Klassen- und Enumerationsdeklarationen, Modul- und Skripterkennung, Paketverwaltung und -installation, OData-Endpunktzugriff, erweiterte Transkription und Protokollierung sowie viele weitere Features enthalten. In diesem Artikel bespreche ich jedes dieser Features und stelle Beispiele bereit.

PowerShell wird plattformübergreifend

Sehen wir uns also zuerst das folgende Befehlsskript an, das PowerShell unter Ubuntu 14.04 aus dem Windows PowerShell-Host installiert. Der Screenshot zeigt die Ausführungssitzung aus Windows Bash in Abbildung 1. Wenn Sie nicht mit Bash unter Ubuntu mit dem Windows 10 Anniversary Update vertraut sind, lesen Sie „Installieren von Bash unter Windows 10“:

wget -O powershell.deb https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/powershell_6.0.0-alpha.9-1ubuntu1.14.04.1_amd64.deb
sudo apt-get install libunwind8 libicu52
sudo dpkg -i powershell.deb
powershell

Installieren und Ausführen von Windows PowerShell unter Ubuntu 14.04 aus Bash unter Ubuntu in Windows
Abbildung 1: Installieren und Ausführen von Windows PowerShell unter Ubuntu 14.04 aus Bash unter Ubuntu in Windows

Beachten Sie, dass das Befehlsskript speziell für Ubuntu 14.04 konzipiert ist. Für andere Plattformen unterscheiden sich die URL des DEB-Pakets und die Voraussetzungsversionen. Unter bit.ly/2bjAJ3H finden Sie Anleitungen für Ihre jeweilige Plattform.

Vor inzwischen vielen Jahren hat Jeffrey Snover in einem Tweet mitgeteilt, dass die Verwendung von PowerShell unter Linux in greifbarer Nähe sei. Es hat jedoch noch so lange gedauert, und es gab nur wenige Berichte über den Fortschritt. Ich bin selbst heute noch überrascht, während ich PowerShell verwende. Also, das ist wirklich möglich? Ich führe Bash unter Ubuntu in Windows aus (ohne Virtualisierungstechnologie zu nutzen) und verwende (da ich PowerShell nicht direkt in die gleiche Bash-Instanz installieren möchte) SSH zum Herstellen einer Verbindung mit einer Bash-Remotesitzung, in der ich PowerShell installieren und .NET-Objekte zwischen Befehlen in der Bash-Shell weiterreichen kann.

Wenn ich vor einigen Jahren behauptet hätte, dass dies möglich sei, hätten mir die wenigsten Benutzer Glauben geschenkt.

Installieren von Bash unter Windows 10

Ab Windows 10 Anniversary Edition kann Bash nativ unter Windows mit dem folgenden Windows PowerShell-Befehl installiert werden:

Get-WindowsOptionalFeature -Online -FeatureName *linux* | Enable-WindowsOptionalFeature -NoRestart -all –online

Beachten Sie jedoch, dass es sich noch um die Betaversion handelt, die daher nur im Entwicklermodus aktiviert ist (verwenden Sie „Get-Help WindowsDeveloper“, um herauszufinden, wie der Entwicklermodus verwendet wird).

Leider erfordert dieses Feature einen Neustart. Ich schließe jedoch die Option „-NoRestart“ ein, damit beim Aktivieren des Features nicht direkt ein Neustart ausgelöst wird.

PowerShell-Repositorys und der PowerShell-Katalog

Natürlich ist es großartig, dass Sie Ihre eigenen Skripts und Bibliotheken erstellen können. Wahrscheinlich hat aber schon ein anderer Benutzer in der Community eine ähnliche Aufgabe ausgeführt, die Sie nutzen und optimieren können. Vor der Einführung des PowerShell-Katalogs (PowerShellGallery.com), mussten Sie jedoch das Internet durchforsten, um nach Skripts und Modulen zu suchen, die ggf. hilfreich sein könnten. Und zwar unabhängig davon, ob es sich um Beiträge der Community oder offizielle PowerShell-Produktreleases wie Pscx oder das Posh-Git-Modul handelte. Eine der neueren PowerShell-Optimierungen (Bestandteil von PowerShell 5.0), die ich unter keinen Umständen mehr missen möchte, ist die neue Repositoryunterstützung (insbesondere im PowerShell-Katalog). Angenommen, Sie arbeiten schon seit einiger Zeit mit PowerShell. Dabei ist Ihnen aufgefallen, dass zahlreiche Fallstricke vorhanden sind, die vermieden werden müssen. Wenn Sie doch nur Ihren Code analysieren und diese ermitteln könnten! Vor diesem Hintergrund könnten Sie zum PowerShell-Katalog navigieren und nach einem Analysemodul suchen, das Sie installieren können. Eine noch bessere Lösung (weil Sie wahrscheinlich bereits ein PowerShell-Fenster geöffnet haben) besteht im Nutzen des Befehls „Find-Module“ des PowerShellGet-Moduls (in PowerShell 5.0 enthalten):

Find-Module *Analyze* | Select-Object Name,Description

Die entsprechende Ausgabe wird in Abbildung 2 gezeigt.

Ausgabe des Befehls „Find-Module“
Abbildung 2: Ausgabe des Befehls „Find-Module“

Beachten Sie, dass ein NuGet-Paketupdate ausgelöst wird, wenn Sie das PowerShellGet-Modul nutzen und keine ausreichend aktuelle Version von NuGet installiert ist.

Angenommen, Sie haben das gewünschte Modul gefunden. Sie können nun seinen Inhalt über den Befehl „Save-Module“ anzeigen. Verwenden Sie zum Installieren des Moduls den Befehl „Install-Module“ (in diesem Fall „Install-Module PSScriptAnalyzer“). Das Modul wird dann heruntergeladen und für Sie installiert. Alle im Modul enthaltenen Funktionen sind damit verfügbar. Nachdem das PSScriptAnalyzer-Modul installiert wurde, können Sie „Invoke-ScriptAnalyzer $profile“ aufrufen, um Ihr Profil zu scannen und Probleme zu identifizieren, die die Analyse als suboptimal eingestuft hat. (Beachten Sie, dass es nicht mehr erforderlich ist, ein Modul zu importieren, um darauf zugreifen zu können. Die Modulfunktionen werden automatisch so indiziert, dass beim Aufrufen einer Modulfunktion das Modul automatisch importiert wird und bei Bedarf darauf zugegriffen werden kann.)

Beachten Sie, dass der PowerShell-Katalog standardmäßig als Repository konfiguriert ist:

>Get-PSRepository
Name         InstallationPolicy   SourceLocation
----         ------------------   --------------
PSGallery    Untrusted            https://www.powershellgallery.com/api/v2/

Daher funktioniert „Find-Module“ problemlos. „Install-Module“ gibt aber eine Warnung aus, dass ein nicht vertrauenswürdiges Repository vorliegt. Wenn Sie dem Repository jedoch vertrauen, können Sie es mit dem folgenden Befehl als vertrauenswürdig festlegen, um diese Warnung zu vermeiden:

Set-PSRepository -Name PSGallery -InstallationPolicy Trusted

„Apt-Get“ für Windows mit PowerShell-Paketverwaltung

Diejenigen von Ihnen, die bereits als IT-Profi in der Linux-Welt gearbeitet haben, halten „apt-get“ zweifellos für selbstverständlich, insbesondere mit Installationsskripts, die Bootstrapping ihrer Umgebung in dem Moment ausführen, in dem eine neue Linux-Instanz gestartet wird. Wenn dies auf Sie nicht zutrifft: „apt-get“ bietet die Möglichkeit, Programme/Pakete und ihre Abhängigkeiten direkt über die Befehlszeile schnell und einfach aus dem Internet herunterzuladen und zu installieren. Abbildung 1 zeigt ein triviales Beispiel für eine solche Installation. „apt-get“ wird zum Installieren von libunwind8 libicu52 genutzt, einer erforderlichen Abhängigkeit für PowerShell (unter Ubuntu 14.04). Mit PowerShell 5.0 ist diese gleiche Funktion nun auch für Windows verfügbar (ich bin mir nicht sicher, ob ich „Hurra!“ schreien oder entnervt „Endlich!“ seufzen soll. Wahrscheinlich beides).

Für PowerShell-Module sind Repositorys wie der PowerShell-Katalog verfügbar. PowerShell 5.0 enthält ebenfalls Unterstützung zum Verwalten von Programmen (die als Pakete bezeichnet werden) in Windows. Einer dieser Paket-Manager ist Chocolatey (chocolatey.org). Sie können ihn als Paketrepository mithilfe des folgenden Befehls hinzufügen:

Get-PackageProvider -Name chocolatey

Auf diese Weise können Sie PowerShell zum Suchen nach Paketen verwenden, die in Chocolatey bereitgestellt wurden. Wenn Sie z. B. Visual Studio Code installieren möchten, müssen Sie nur die folgenden Befehle eingeben:

Find-Package V*S*Code | Install-Package

Wie das Beispiel zeigt, werden Platzhalter unterstützt.

Weitere Paketbefehle, mit denen Sie vertraut sein sollten, stehen mit dem folgenden Befehl zur Verfügung. Die Ergebnisse werden in Abbildung 3 gezeigt:

Get-Help "-package" | Select-Object Name,Synopsis

Verfügbare Windows PowerShell-Paketbefehle
Abbildung 3:Verfügbare Windows PowerShell-Paketbefehle

Wie Sie sehen, können Sie Pakete abrufen und deinstallieren. „Get-Package“ listet alle verfügbaren Programme (und mehr) aus „Programme und Features“ in der Systemsteuerung auf. Wenn Sie z. B. Notepad2 deinstallieren möchten, verwenden Sie den folgenden Befehl:

Get-Package Notepad2* | Uninstall-Package

Auf diese Weise wird die Automatisierung des Windows-Computersetups erheblich vereinfacht. Ich bin schon seit Jahren ein Fan von Chocolatey, und diese Neuerung integriert die Chocolatey-Unterstützung direkt in Windows. Endlich ist Paketverwaltung in Windows auf ähnliche Weise wie mit „Apt-Get“ unter Linux verfügbar.

Beachten Sie Folgendes: Auf das Chocolatey-Repos­itory kann nicht nur über die PowerShell-Befehle *-package* zugegriffen werden, sondern Chocolatey kann auch direkt installiert werden. Dies ist zwar nicht erforderlich, doch die direkte Installation von Chocolatey kann ggf. eine robustere Featuresammlung von Paketverwaltungsfunktionen bereitstellen. Glücklicherweise (und vielleicht ironischerweise) muss zum Installieren von Chocolatey einfach nur „Install-Package Chocolatey“ aufgerufen werden. Der Standardspeicherort für die Installation (und dies ist ein Beispiel für die Unterschiede zwischen dem Chocolatey- und dem *-Package*-Verhalten) hängt jedoch davon ab, welches Installationsmodul verwendet wird. Weitere Informationen zum Chocolatey-Toolset (einschließlich Installationsanleitungen für Ihre Umgebung) finden Sie unter „chocolatey.org/install“.

OData mit Export-ODataEndpointProxy

Ein weiteres Feature von PowerShell 5.0, das erwähnt werden muss, ist die Möglichkeit, eine Sammlung von Methoden zu generieren, die auf eine OData-Datenquelle (z. B. Visual Studio Team Services, VSTS) zugreifen. Abbildung 4 zeigt die Ausführung von „Export-ODataEndpointProxy“ für einen OData-Dienst (in diesem Fall für einen öffentlichen Northwind OData-Beispieldienst).

Generieren und Aufrufen eines OData-Proxys
Abbildung 4: Generieren und Aufrufen eines OData-Proxys

Wenn Sie die generierten Modulbefehle untersuchen, wird Ihnen auffallen, dass separate Befehle für jede Entität (Advertisement, Category, Person usw.) zusammen mit den entsprechenden Aktionen für jede Entität („Get“, „New“, „Remove“, „Set“) generiert werden.

Beachten Sie in der Befehlszeile in Abbildung 4 die Verwendung des -AllowUnsecureConnection-Parameters. Dieser ist erforderlich, weil der in diesem Beispiel verwendete OData-Dienst keine Authentifizierung oder Verschlüsselung erfordert.

Konvertieren aus Text in Objekte mit „ConvertFrom-String“

Ein weiterer neuer Befehl in PowerShell 5.0 ist „ConvertFrom-String“. Dieser nimmt strukturierten Text als Eingabe an und interpoliert die Struktur so, dass die Ausgabe ein Objekt ist, das auf dem analysierten Text basiert. Sie können dieses Feature z. B. verwenden, um eine Flatfile zu analysieren oder (und hier finde ich den Befehl ausgesprochen nützlich) die Textausgabe aus einer ausführbaren Datei in ein Objekt zu konvertieren.

Nehmen Sie als Beispiel das Programm „handle.exe“ von SysInternal (das Sie mit dem Befehl „Install-Package Handle“ unter Nutzung der im vorherigen Abschnitt beschriebenen Paketverwaltung installieren können). Wie Sie es von einem Befehlszeilenprogramm erwarten, wird Text an „stdout“ ausgegeben. In diesem Fall eine Liste der geöffneten Handles, die einem Namen zugeordnet sind. In PowerShell haben Sie sich jedoch daran gewöhnt, mit Objekten zu arbeiten. Zum Konvertieren der Textausgabe in ein Objekt verwenden Sie die Funktion „ConvertFrom-String“. Abbildung 5 zeigt dies.

Verwenden von „ConvertFrom-String“ zum Analysieren von „stdout“ in ein Objekt
Abbildung 5: Verwenden von „ConvertFrom-String“ zum Analysieren von „stdout“ in ein Objekt

Abbildung 5 zeigt zuerst die Rohausgabe des Hilfsprogramms „handle.exe“. Anschließend wird „ConvertFrom-String“ ohne Parameter gezeigt. Als Ergebnis teilt das Hilfsprogramm „ConvertFrom-String“ den Text in jeder Zeile einfach basierend auf Leerzeichen auf.

Im dritten Beispiel zeige ich die Option, ein Aufteilungsmuster als regulären Ausdruck anzugeben, um die Analyse zu optimieren. Die Vertrautheit mit regulären Ausdrücken ist jedoch nicht unbedingt erforderlich. Sie können stattdessen eine Vorlage (genauer gesagt, ein Beispiel) einer Datei oder einer Zeichenfolge angeben, in der Sie die ersten Elemente manuell analysieren. „ConvertFrom-String“ nutzt dann den als Beispiel analysierten Inhalt, und interpretiert, wie die restliche Eingabe analysiert werden soll.

Im letzten Beispiel habe ich den Parameter „-PropertyNames“ hinzugefügt, um der Ausgabe aussagekräftige Namen zuzuweisen.

Letztlich überbrückt „ConvertFrom-String“ den Impedanzkonflikt zwischen der textbasierten Welt von traditionellem Prozess-stdout und der objektbasierten Power­Shell-Welt. In diesem Fall kann ich die Ausgabe an „Stop-Process -Id“ weiterreichen und den PID-Wert dem -Id-Parameterwert zuordnen.

Klassen und Enumerationen

Abschließend möchte ich noch die Unterstützung für neue Klassen und Enumerationen zusammenfassen. In PowerShell 5.0 wurden zwei neue Schlüsselwörter entsprechend den beiden Strukturen hinzugefügt, damit Sie nun eine Klasse oder eine Enumeration direkt in PowerShell deklarieren können (anstatt „Add-Type“ zu verwenden und C#-Code zu übergeben oder ggf. ein „PSCustom­Object“ zu instanziieren). Die Syntax stellt keine Überraschung dar: siehe Abbildung 6.

Abbildung 6: Deklarieren von Klassen und Enumerationen in Windows PowerShell

enum CustomProcessType {
  File
  Section
}
class CustomProcess {
  [string]$ProcessName;
  hidden [string]$PIDLabel;
  [int]$PID;
  hidden [string]$TypeLabel;
  [CustomProcessType]$Type;
  [int]$Handle;
  [string]$Path;
  CustomProcess(
    [string]$processName,[string]$pidLabel,[int]$pid,
    [string]$typeLabel,[string]$type,[int]$handle,[string]$path) {
    $this.ProcessName = $processName;
    $this.PIDLabel=$pidLabel;
    $this.PID=$pid;
    $this.TypeLabel=$typeLabel;
    $this.Type=$type;
    $this.Handle=$handle;
    $this.Path=$path;
  }
  CustomProcess() {}
  GetProcess() {
    Get-Process -Id $this.PID
  }
  static StopProcess([CustomProcess]$process) {
    Stop-Process -Id $process.PID
  }
}

Beachten Sie besonders, dass beide Eigenschaften und Methoden unterstützt werden. Außerdem sind Deklarationsmodifizierer wie „static“ und „hidden“ verfügbar, die das zugehörige Konstrukt entsprechend festlegen. Darüber hinaus wird Vererbung mit einer Syntax unterstützt, die der Syntax von C# sehr ähnlich ist:

class Employee : Person {}

Schließlich (ebenfalls in Abbildung 6 gezeigt) können Konstruktoren deklariert werden. In diesem Beispiel deklariere ich einen Standardkonstruktor (ohne Parameter) sowie einen zweiten Konstruktor, der alle Parameter annimmt. Die Konstruktoren werden über den Befehl „New-Object“ aufgerufen, indem der Parameter „-ArgumentList“ (durch den ein Array von Konstruktorargumenten aufgelistet wird) oder ein HashTable-Argument über den Parameter „-Property“ angegeben wird.

Zusammenfassung

Dies ist keineswegs eine vollständige Liste der neuen Features in PowerShell 5.0. Die folgenden Features sind ebenfalls erwähnenswert:

  • Integration von Archiven (Unterstützung für ZIP-Dateien) über die Befehle „Compress-Archive“ und „Expand-Archive“.
  • Die Befehle „Get-Clipboard“ und „Set-Clipboard“, die auch mit dem Pipeoperator funktionieren.
  • „Out-File“, „Add-Content“ und „Set-Content“ enthalten einen Parameter „-NoNewline“, der Dateiinhalte ermöglicht, in denen das Neue-Zeile-Zeichen ausgelassen wird.
  • Der Befehl „New-TemporaryFile“ besitzt eine ähnliche Funktion wie „[System.IO.Path]::GetTempFileName“ (die Funktionsweise ist jedoch nicht identisch). Wie sein .NET-Äquivalent löscht der Befehl „ New-TemporaryFile“ die temporäre Datei nicht. Stellen Sie daher sicher, das die Ausgabe gespeichert wird, damit Sie die Datei entfernen können, wenn Sie sie nicht mehr benötigen.
  • „SymbolicLinks“ kann nun direkt über die PowerShell-Cmdlets „New-Item“ und „Remove-Item“ verwaltet werden.
  • Die PowerShell ISE (Integrated Scripting Environment) unterstützt nun die Protokollierung über die Funktionen „Start/Stop/Search-Transcript“. Früher trat ein Fehler auf, wenn der Aufruf aus der PowerShell ISE erfolgte.

Außerdem plant Microsoft die vollständige Unterstützung von Open SSH, auch wenn diese nicht sofort im Open Source-Release von PowerShell erfolgt. Dabei wird es sich um eine Remotingtransportoption in PowerShell sowie in der Windows-Remoteverwaltung handeln. Die Bereitstellung wird kurz nach der Veröffentlichung dieses Artikels erfolgen.

Durch alle diese Möglichkeiten wird PowerShell immer besser und besser. Wenn Sie PowerShell noch nicht kennen, sollten Sie dies schleunigst ändern.


Mark Michaelis ist der Gründer von IntelliTect und arbeitet als leitender technischer Architekt und Trainer. Seit fast zwei Jahrzehnten ist er ein Microsoft MVP und seit 2007 Microsoft-Regionalleiter. Michaelis arbeitet in verschiedenen Microsoft-Softwareentwicklungs-Reviewteams mit, einschließlich C#, Microsoft Azure, SharePoint und Visual Studio ALM. Er hält häufig Vorträge bei Entwicklerkonferenzen und hat viele Bücher geschrieben, einschließlich seines letzten „Essential C# 6.0 (5th Edition)“.  Nehmen Sie auf Twitter @markmichaelis oder per E-Mail unter mark@IntelliTect.com Kontakt mit ihm auf.

Unser Dank gilt den folgenden technischen Experten von IntelliTect für die Durchsicht dieses Artikels: Kevin Bost, Phil Spokas und Michael Stokesbary