Grundlagen für die DevOps-Welt – Teil 2

PowerShell-Grundlagen: Bearbeitung von Cmdlet-Ergebnissen
Kommentare

Für viele .NET-Entwickler ist die PowerShell noch immer ein Buch mit sieben Siegeln und wird oft in die Sysadmin-Ecke verstoßen. Schade eigentlich, denn die PowerShell hat das Potenzial, den Entwickleralltag um einiges produktiver und angenehmer zu gestalten. Welche Vorteile die PowerShell mit sich bringt, zeigt diese Artikelserie. Der zweite Teil beschäftigt sich mit der Bearbeitung und Weiterverarbeitung von Cmdlet-Ergebnissen.

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.

Artikelserie
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

Schnell und überall: Datenzugriff mit Entity Framework Core 2.0

Dr. Holger Schwichtenberg (www.IT-Visions.de/5Minds IT-Solutions)

C# 7.0 – Neues im Detail

Christian Nagel (CN innovation)

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"
Abb. 2: Das Resultat der „Get-Service“-Abfrage mit „ConvertTo-Html“ im Edge-Browser

Abb. 2: Das Resultat der „Get-Service“-Abfrage mit „ConvertTo-Html“ im Edge-Browser

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).

Abb. 3: Das WPF-Fenster von „Out-GridView“

Abb. 3: Das WPF-Fenster von „Out-GridView“

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

Windows DeveloperDieser 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. In unserem Shop ist der Windows Developer ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -