Mal schnell sieben Frontend-Webserver neustarten? Eine virtuelle Maschine in Azure hochfahren? Aus den Services im Backend eine HTML-Datei generieren? Ein Back-up einer SQL-Server-Datenbank erstellen? Auf der Webserverfarm einen neuen Application Pool einrichten? Mit dem wachsenden DevOps-Bedürfnis, welches nach dem Verschmelzen von Entwicklung und Betrieb strebt, wird die PowerShell in Zukunft auch für Entwickler stark an Bedeutung gewinnen. Diese Artikelserie wird Entwickler Schritt für Schritt an die PowerShell heranführen und erklären, wie man diese in den DevOps-Alltag integrieren kann. Nachdem wir im ersten Teil zuerst einen Blick auf die PowerShell-Grundlagen und eine Einführung in Cmdlets geworfen haben, geht es jetzt im zweiten Teil um die Bearbeitung und Weiterverarbeitung von Cmdlet-Ergebnissen. Der dritte und letzte Teil behandelt dann Praxisbeispiele aus dem DevOps-Alltag.
Teil 1: PowerShell-Grundlagen: Hilfe, wie geht’s los?
Teil 2: PowerShell-Grundlagen: Bearbeitung und Weiterverarbeitung von Cmdlet-Ergebnissen
Teil 3: Praxisbeispiele aus dem DevOps-Alltag
Formatierung der Ausgabe
Die PowerShell bietet einige Cmdlets zur Formatierung von Cmdlet-Ergebnissen. Als Erstes muss entschieden werden, ob die Daten in Form einer Liste oder einer Tabelle dargestellt werden sollen. Im Beispiel werden wieder die größten Dateien aus dem D:\__TEMP-Verzeichnis und allen Unterverzeichnissen geladen. Mit dem Cmdlet Select-Object werden der Name, die Größe und das Erstellungsdatum der Datei ausgewählt. Ohne Angabe einer Formatierung wird das Resultat tabellarisch dargestellt (Listing 4). Für die weiteren Beispiele wird das Resultat von Get-ChildItem in der Variable $bigFiles zwischengespeichert.
Listing 4: Formatierung als Tabelle PS C:\> $bigFiles = Get-ChildItem D:\__TEMP -Recurse | Sort-Object Length -Descending | Select-Object Name, Length, CreationTime, LastAccessTime -First 5 PS: C:\> $bigFiles Name Length CreationTime ---- ------ ------------ 1246_glimpsev2.mp3 57537015 09.02.2016 00:02:40 1252_numl.mp3 56507999 09.02.2016 00:01:55 1242_messaging.mp3 56176140 09.02.2016 00:06:59 1253_onboarding_is_culture.mp3 53080948 09.02.2016 00:01:32 1248_microservices_in_azure.mp3 52134474 09.02.2016 00:02:20
Alternativ zur Ausgabe als Tabelle kann das Resultat durch Anhängen von Format-List auch als Liste ausgegeben werden (Listing 5). Im Beispiel wird die Auswahl der Spalten bereits in der Abfrage definiert. Oft ist es aber sinnvoller, als Resultat der Abfrage alle Spalten zu erhalten und erst bei der Formatierung die Auswahl zu treffen. Die anzuzeigenden Spalten können den Format-Cmdlets als Parameter mitgegeben werden: Format-List –Property Name, Length.
Als Bemerkung ist noch zu erwähnen, dass die PowerShell ohne Angabe von Properties jeweils nur Standard-Properties anzeigt. Um die vollständige Liste zu erhalten, muss der Property-Parameter mit dem Stern angehängt werden: Format-List –Property *.
Listing 5: Formatierung als Liste PS: C:\> $bigFiles | Format-List Name : 1246_glimpsev2.mp3 Length : 57537015 CreationTime : 09.02.2016 00:02:40 Name : 1252_numl.mp3 Length : 56507999 CreationTime : 09.02.2016 00:01:55 Name : 1242_messaging.mp3 Length : 56176140 CreationTime : 09.02.2016 00:06:59 …
Eine weitere nützliche Funktion ist die Gruppierung von tabellarischen Daten. Listing 6 zeigt, wie die Daten aus dem Beispiel zusätzlich nach dem ReadOnly-Flag gruppiert werden können.
Listing 6: Gruppierung von Daten PS: C:\> $bigFiles | sort IsReadOnly -d | ft -GroupBy IsReadOnly IsReadOnly: True Name Length CreationTime IsReadOnly ---- ------ ------------ ---------- 1246_glimpsev2.mp3 57537015 09.02.2016 00:02:40 True 1242_messaging.mp3 56176140 09.02.2016 00:06:59 True IsReadOnly: False Name Length CreationTime IsReadOnly ---- ------ ------------ ---------- 1252_numl.mp3 56507999 09.02.2016 00:01:55 False 1253_onboarding_is_culture.mp3 53080948 09.02.2016 00:01:32 False 1248_microservices_in_azure.mp3 52134474 09.02.2016 00:02:20 False
Weiterleiten der Ausgabe
Ein sehr mächtiges Feature der PowerShell ist die Weiterleitung und die Konvertierung von Ergebnissen einer Cmdlet-Abfrage. Angenommen, das Resultat aus dem letzten Beispiel soll in eine Datei geschrieben werden. Nichts einfacher als das! Mit dem Cmdlet Out-File wird das Resultat in eine Datei geschrieben:
$bigFiles | Out-File D:\bigFiles.txt
Angenommen, die Datei soll maschinell weiterverarbeitet werden, dann ist die tabellarische Darstellung nicht sehr sinnvoll. Mit dem Cmdlet Export-Csv kann die Tabelle als *.csv-Datei (Comma Separated Values) exportiert und danach beispielsweise in Excel geöffnet werden (Listing 7).
Listing 7: Export der Resultate als Csv-Datei PS: C:\> $bigFiles | Export-Csv D:\bigFiles.csv #TYPE Selected.System.IO.FileInfo "Name","Length","CreationTime","IsReadOnly" "1246_glimpsev2.mp3","57537015","09.02.2016 00:02:40","True" "1252_numl.mp3","56507999","09.02.2016 00:01:55","False" "1242_messaging.mp3","56176140","09.02.2016 00:06:59","True" "1253_onboarding_is_culture.mp3","53080948","09.02.2016 00:01:32","False" "1248_microservices_in_azure.mp3","52134474","09.02.2016 00:02:20","False"
In den ConvertTo-Cmdlets gibt es weitere Möglichkeiten, um die Formatierung zu ändern. Listing 8 zeigt, wie das Resultat unserer Abfrage in die Formate JSON, HTML, XML und CSV konvertiert werden kann.
Listing 8: Konvertierung in JSON, HTML, XML, CSV PS: C:\> $bigFiles | ConvertTo-Json [ { "Name": "1246_glimpsev2.mp3", "Length": 57537015, "CreationTime": "\/Date(1454972560452)\/", "IsReadOnly": true }, { "Name": "1252_numl.mp3", "Length": 56507999, "CreationTime": "\/Date(1454972515623)\/", "IsReadOnly": false } ] PS: C:\> $bigFiles | ConvertTo-Html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>HTML TABLE</title> </head> <body> <table> <colgroup><col/><col/><col/><col/></colgroup> <tr><th>Name</th><th>Length</th><th>CreationTime</th><th>IsReadOnly</th></tr> <tr><td>1246_glimpsev2.mp3</td><td>57537015</td><td>09.02.2016 00:02:40</td><td>True</td></tr> <tr><td>1252_numl.mp3</td><td>56507999</td><td>09.02.2016 00:01:55</td><td>False</td></tr> </table> </body> </html> PS: C:\> $xml = $bigFiles | ConvertTo-Xml PS: C:\> $xml.Save(“D:\bigFiles.xml”) <?xml version="1.0"?> <Objects> <Object> <Property Name="Name">1246_glimpsev2.mp3</Property> <Property Name="Length">57537015</Property> <Property Name="CreationTime">09.02.2016 00:02:40</Property> <Property Name="IsReadOnly">True</Property> </Object> <Object> <Property Name="Name">1252_numl.mp3</Property> <Property Name="Length">56507999</Property> <Property Name="CreationTime">09.02.2016 00:01:55</Property> <Property Name="IsReadOnly">False</Property> </Object> </Objects> PS: C:\> $bigFiles | ConvertTo-Csv "Name","Length","CreationTime","IsReadOnly" "1246_glimpsev2.mp3","57537015","09.02.2016 00:02:40","True" "1252_numl.mp3","56507999","09.02.2016 00:01:55","False"
Vor allem die Konvertierung nach HTML ist sehr spannend. Denkbar ist zum Beispiel, auf einem Applikationsserver in regelmässigen Zeitabständen einen Report zu erstellen, der anzeigt, welche Windows-Services einer Anwendung gerade laufen. Mit PowerShell kein Problem. Das folgende Statement erstellt einen solchen Report, der direkt im Browser geöffnet werden kann (Abb. 2):
PS C:\> Get-Service | Select-Object Name, Status -First 10 |Sort-Object Status -Descending | ConvertTo-Html | Out-File "D:\ServiceReport.html"
Eine weitere spannende Ausgabemöglichkeit ist das Out-GridView-Cmdlet. Werden die Resultate der Abfrage aus dem Beispiel mit dem Pipe-Operator an Out-GridView weitergeleitet, öffnet sich ein Windows-Presentation-Foundation-(WPF-)Fenster, das die Liste anzeigt und Funktionen zum Suchen und Filtern bietet (Abb. 3).
Filtern von Resultaten
Ist die Resultatmenge groß, muss durch einen Filter auf die relevanten Objekte eingeschränkt werden. Gefiltert wird in der PowerShell mit dem Where-Object-Cmdlet. Dabei können folgende Vergleichsoperatoren verwendet werden:
- Gleich (equal): -eq
- Ungleich (not equal): -ne
- Kleiner (less than): -lt
- Kleiner oder gleich (less than or equal): -le
- Größer (greater than): -gt
- Größer oder gleich (greater than or equal): -ge
- Enthält (contains): -contains
- Enthält nicht (not contains): -notcontains
- Ähnlich (like): -like, -notlike
- Match (match/notmatch): -match, -notmatch
- Ersetzen (replace): -replace
Die contains-, like- und match-Operatoren führen zu ähnlichen Resultaten. Match sucht eine Zeichenkette an einer beliebigen Stelle und kann mit einer Regular Expression (RegEx) benutzt werden. Like vergleicht zwei Zeichenketten auf Gleichheit, wobei die Platzhalter * (beliebige Anzahl Zeichen) und ? (genau ein Zeichen) verwendet werden können. Contains wird benutzt, um zu prüfen, ob ein bestimmtes Element in einer Liste vorkommt.
Im Beispiel sollen alle Windows-Services angezeigt werden, welche den Status Running besitzen und den Text Network im Namen enthalten:
PS C:\> Get-Service | Where-Object {($_.Status -eq "Running") -and ($_.Name -match "Network")}
Die Liste, die Get-Service zurückgibt, wird durchlaufen, und $_ enthält das Objekt des aktuellen Durchlaufs, analog zu einer foreach-Schleife in C#. Mit der Punktnotation wird auf die Members des Objekts zugegriffen, um diese zu vergleichen. Mehrere Vergleichsoperationen können mit -and und -or logisch verknüpft werden. Zum Schluss noch ein Hinweis: Where-Object kann entweder mit where oder noch kürzer mit ? abgekürzt werden.
Zusammenfassung
Die PowerShell hat jeder Windows-Benutzer immer dabei. Durch die Integration mit .NET, WMI, COM, der Registry und allen verbreiteten Microsoft-Produkten ist sie ein sehr mächtiges Werkzeug. Dieser Artikel zeigte die Grundlagen zum Umgang mit der PowerShell . Im zweiten Teil geht es um fortgeschrittene Konzepte und um praktische Anwendungsbeispiele für den Alltag des Softwareentwicklers.
Im dritten Teil der Artikelserie wird es endlich etwas handfester: Wir behandeln Praxisbeispiele aus dem DevOps-Alltag.
Windows Developer
Dieser Artikel ist im Windows Developer erschienen. Windows Developer informiert umfassend und herstellerneutral über neue Trends und Möglichkeiten der Software- und Systementwicklung rund um Microsoft-Technologien.
Natürlich können Sie den Windows Developer über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. Außerdem ist der Windows Developer weiterhin als Print-Magazin im Abonnement erhältlich.