Historisch gesehen sind die Kommandozeilen-Tools in Unix-Systemen besser entwickelt als in Windows, jedoch hat sich mit dem neuen Ansatz die Situation geändert.
PowerShell ermöglicht das Schreiben von Skripten in einer interpretierbaren, multiparadigmatischen Sprache, die Elemente der klassischen prozeduralen, objektorientierten und sogar funktionalen Programmierung enthält: bedingte Anweisungen, Schleifen, Variablen, Arrays, Hash-Tabellen, Klassen, Fehlerbehandlung sowie Funktionen, Cmdlets und Pipelines. Während wir zuvor die Grundlagen der Arbeit in dieser Umgebung behandelt haben, möchten wir nun unseren Lesern ein kleines Handbuch für Programmierer anbieten.
Inhaltsverzeichnis:
Code kann in jedem Texteditor oder unter Verwendung einer integrierten Entwicklungsumgebung geschrieben werden – am einfachsten ist es, Windows PowerShell ISE aus dem Lieferumfang der Microsoft Serverbetriebssysteme zu verwenden. Dies ist nur für ausreichend komplexe Skripte erforderlich: Kurze Befehlsfolgen lassen sich einfacher im interaktiven Modus ausführen.
Kommentare
Die Verwendung von Kommentaren gilt als Teil eines guten Programmierstils, neben korrektem Einrücken und Abstand:
# Для строчных комментариев используется символ решетки — содержимое строки интерпретатор не обрабатывает.
<#
Так обозначаются начало и конец блочного комментария.
Заключенный между ними текст интерпретатор игнорирует.
#>
Variablen und ihre Typen
Variablen in PowerShell sind benannte Objekte. Ihre Namen können Unterstriche sowie Buchstaben und Zahlen enthalten. Ein $-Symbol steht immer vor dem Namen, und um eine Variable zu deklarieren, reicht es, dem Interpreter einen gültigen Namen anzugeben:

Zur Initialisierung einer Variablen (Zuweisung eines Wertes) wird der Zuweisungsoperator (das Symbol =) verwendet:
$test = 100Eine Variable kann unter Angabe ihres Typs in eckigen Klammern (Typumwandlungsoperator) vor dem Namen oder dem Wert deklariert werden:
[int]$test = 100
$test = [int]100Es ist wichtig zu verstehen, dass Variablen in PowerShell vollständige Objekte (Klassen) mit Eigenschaften und Methoden sind, deren Typen auf den in .NET Core vorhandenen basieren. Hier sind die wichtigsten:
Typ (Klasse .NET)
Beschreibung
Beispielcode
[string]
System.String
Unicode-Zeichenkette
$test = "test"
$test = 'test'
[char]
System.Char
Unicode-Zeichen (16 Bit)
[char]$test = 'c'
[bool]
System.Boolean
Boolescher Typ (logischer Wert True oder False)
[bool]$test = $true
[int]
System.Int32
32-Bit Ganzzahl (32 Bit)
[int]$test = 123456789
[long]
System.Int64
64-Bit Ganzzahl (64 Bit)
[long]$test = 12345678910
[single]
System.Single
32-Bit-Gleitkommazahl
[single]$test = 12345.6789
[double]
System.Double
64-Bit-Gleitkommazahl (8 Byte)
[double]$test = 123456789.101112
[decimal]
System.Decimal
128-Bit-Gleitkommazahl (d muss am Ende angegeben werden)
[decimal]$test = 12345.6789d
[DateTime]
System.DateTime
Datum und Uhrzeit
$test = Get-Date
[array]
System.Object[]
Array, dessen Elementindizes bei 0 beginnen
$test_array = 1, 2, "Test", 3, 4
[hashtable]
System.Collections.Hashtable
Hashtabellen sind assoziative Arrays mit benannten Schlüsseln, aufgebaut nach dem Prinzip: @{Schlüssel = "Wert"}
$test_hashtable = @{one="eins"; two="zwei"; three="drei"}
PowerShell unterstützt implizite Typkonvertierungen, außerdem kann der Typ einer Variablen zur Laufzeit (z. B. durch Zuweisungsoperatoren) geändert werden, sofern er nicht explizit angegeben wird - in diesem Fall gibt der Interpreter einen Fehler aus. Den Typ der Variablen aus dem vorherigen Beispiel kann man durch den Aufruf der Methode GetType() bestimmen:
$test.GetType().FullName 
Es gibt eine Reihe von Cmdlets zur Verwaltung von Variablen. Ihre Liste wird in übersichtlicher Form mit dem Befehl ausgegeben:
Get-Command -Noun Variable | ft -Property Name, Definition -AutoSize -Wrap 
Um die deklarierten Variablen und deren Werte anzuzeigen, kann ein spezielles Cmdlet verwendet werden:
Get-Variable | moreDieser Ansatz erscheint etwas umständlich, da es viel einfacher ist, mit Variablen über Operatoren zu arbeiten oder direkt auf deren Eigenschaften und Methoden zuzugreifen. Dennoch haben Cmdlets ihre Berechtigung, da sie zusätzliche Parameter ermöglichen. Es ist wichtig zu wissen, dass benutzerdefinierte Variablen nur im aktuellen Sitzungskontext definiert sind. Nach dem Schließen der Konsole oder dem Beenden des Skripts werden sie gelöscht.
Systemvariablen
Neben den vom Benutzer deklarierten Variablen gibt es auch integrierte (System-)Variablen, die nach Beendigung der aktuellen Sitzung nicht gelöscht werden. Diese lassen sich in zwei Typen unterteilen, wobei die Informationen über den Zustand von PowerShell in automatischen Variablen gespeichert werden, denen keine willkürlichen Werte zugewiesen werden können. Dazu gehört beispielsweise $PWD:
$PWD.Path 
Für die Speicherung benutzerdefinierter Einstellungen werden Präferenzvariablen benötigt, deren Werte geändert werden können. Zum Beispiel wird mit $ErrorActionPreference das Verhalten des Befehlsinterpreter bei Auftreten von nicht kritischen Fehlern festgelegt.
Zusätzlich zu den Operatoren und Cmdlets, die auf deklarierte Variablen zugreifen, gibt es den Pseudostorage Variable:. Die Arbeit mit ihm ähnelt der mit anderen Speichern, und die Variablen erinnern in diesem Fall an Objekte im Dateisystem:
Get-ChildItem Variable: | moreoder
ls Variable: | more 
Sichtbarkeitsbereiche
Für Variablen in PowerShell gibt es das Konzept des Geltungsbereichs (Scope). Der globale Geltungsbereich (Global) erstreckt sich über die gesamte aktuelle Sitzung – dazu gehören beispielsweise Systemvariablen. Lokale (Local) Variablen sind nur in dem Bereich verfügbar, in dem sie definiert wurden, etwa innerhalb einer Funktion. Es gibt auch das Konzept des Skript-Geltungsbereichs (Script), der für Skriptbefehle praktisch lokal ist. Standardmäßig wird beim Deklarieren von Variablen ein lokaler Geltungsbereich zugewiesen, und um dies zu ändern, ist eine spezielle Konstruktion wie folgt erforderlich: $Global: variable = wert.
Zum Beispiel so:
$Global:test = 100
Umgebungsvariablen
In PowerShell gibt es ein weiteres Pseudolaufwerk Env:, über das Sie auf Umgebungsvariablen zugreifen können. Wenn die Shell gestartet wird, werden diese aus dem übergeordneten Prozess (d.h. dem Programm, das die aktuelle Sitzung eingeleitet hat) kopiert und ihre ursprünglichen Werte stimmen normalerweise mit den Werten in der Systemsteuerung überein. Zum Anzeigen von Umgebungsvariablen verwenden Sie das Cmdlet Get-ChildItem oder seine Aliase: ls und dir.
dir Env: 
Diese Variablen sind Byte-Sequenzen (oder Zeichen, wenn Sie wollen), deren Interpretation nur von dem Programm abhängt, das sie verwendet. Cmdlets *-Variable funktionieren nicht mit Umgebungsvariablen. Um auf sie zuzugreifen, müssen Sie das Laufwerk-Präfix verwenden:
$env:TEST = "Hello, World!" 
Arithmetische Operatoren und Vergleichsoperatoren
In PowerShell gibt es folgende arithmetische Operatoren: + (Addition), — (Subtraktion), * (Multiplikation), / (Division) und % (Modul oder Rest der Division). Das Ergebnis eines arithmetischen Ausdrucks wird von links nach rechts gemäß der allgemeinen Reihenfolge der Operationen berechnet, und zur Gruppierung von Teilen des Ausdrucks werden runde Klammern verwendet. Leerzeichen zwischen den Operatoren werden ignoriert und dienen lediglich der besseren Lesbarkeit. Der Operator + vereint auch, während der Operator * Strings wiederholt. Bei dem Versuch, eine Zahl zu einem String hinzuzufügen, wird diese in einen String umgewandelt. Darüber hinaus gibt es in PowerShell eine Vielzahl von Vergleichsoperatoren, die die Übereinstimmung zwischen zwei Werten überprüfen und logische Werte True oder False zurückgeben:
Der Befehl
Beschreibung
Beispielcode
-eq
Gleich / Equal (entspricht = oder == in anderen Sprachen)
$test = 100
$test -eq 123
-ne
Nicht gleich / Not equal (entspricht oder !=)
$test = 100
$test -ne 123
-gt
Größer als / Greater than (entspricht >)
$test = 100
$test -gt 123
-ge
Größer oder gleich / Greater than or equal (entspricht >=)
$test = 100
$test -ge 123
-lt
Kleiner als / Less than (entspricht <)
$test = 100
$test -lt 123
-le
Kleiner oder gleich / Less than or equal (entspricht <=)
$test = 100
$test -le 123
Es gibt auch andere ähnliche Operatoren, die es ermöglichen, beispielsweise Zeichenfolgen unter Berücksichtigung von Platzhaltersymbolen zu vergleichen oder reguläre Ausdrücke zur Mustererkennung zu verwenden. Diese werden wir in den kommenden Artikeln ausführlich behandeln. Die Symbole und = werden für Vergleiche nicht verwendet, da sie anderen Zwecken dienen.
Zuweisungsoperatoren
Neben dem am häufigsten verwendeten Operator = gibt es auch andere Zuweisungsoperatoren: +=, -=, *=, /= und %=, die den Wert vor der Zuweisung ändern. Ähnlich verhalten sich die unären Operatoren ++ und —, die den Wert einer Variablen erhöhen oder verringern — sie gehören ebenfalls zu den Zuweisungsoperatoren.
Logische Operatoren
Um komplexe Bedingungen zu beschreiben, reicht ein einfacher Vergleich nicht aus. Jede logische Ausdrucksform kann mit den Operatoren -and, -or, -xor, -not und ! erstellt werden. Sie funktionieren wie in anderen Programmiersprachen, wobei runde Klammern verwendet werden können, um die Reihenfolge der Berechnungen festzulegen:
("Test" -eq "Test") -and (100 -eq 100)
-not (123 -gt 321)
!(123 -gt 321)
Bedingte Anweisungen
Die Verzweigungsoperatoren in PowerShell sind standardmäßig: IF (IF…ELSE, IF…ELSEIF…ELSE) und SWITCH. Lassen Sie uns ihre Verwendung anhand von Beispielen betrachten:
[int]$test = 100
if ($test -eq 100) {
Write-Host "test = 100"
}
[int]$test = 50
if ($test -eq 100) {
Write-Host "test = 100"
}
else {
Write-Host "test 100"
}
[int]$test = 10
if ($test -eq 100) {
Write-Host "test = 100"
}
elseif ($test -gt 100) {
Write-Host "test > 100"
}
else {
Write-Host "test 5 oder Wert nicht definiert"}
}
Schleifen
In PowerShell gibt es verschiedene Arten von Schleifen: WHILE, DO WHILE, DO UNTIL, FOR und FOREACH.
Eine Bedingungs-Schleife funktioniert, wenn/bis die Bedingung erfüllt ist:
[int]$test = 0
while ($test -lt 10) {
Write-Host $test
$test = $test + 1
}
Postbedingte Schleifen werden mindestens einmal durchlaufen, da die Bedingung nach der Iteration überprüft wird. DO WHILE läuft, solange die Bedingung wahr ist, und DO UNTIL läuft, solange sie falsch ist:
[int]$test = 0
do {
Write-Host $test
$test = $test + 1
}
while ($test -lt 10)
[int]$test = 0
do {
Write-Host $test
$test = $test + 1
}
until ($test -gt 9)
Die Anzahl der Iterationen in einer FOR-Schleife ist im Voraus bekannt:
for ([int]$test = 0; $test -lt 10; $test++) {
Write-Host $test
}
In der FOREACH-Schleife werden die Elemente eines Arrays oder einer Sammlung (Hash-Tabellen) durchlaufen:
$test_collection = "item1", "item2", "item3"
foreach ($item in $test_collection)
{
Write-Host $item
}
Arrays
In PowerShell-Variablen werden nicht nur Einzelobjekte (Zahl, Zeichenfolge usw.) gespeichert, sondern auch mehrere. Die einfachste Art solcher Variablen sind Arrays. Ein Array kann aus mehreren Elementen, einem einzelnen Element oder leer sein, das heißt, es enthält keine Elemente. Zur Erklärung verwenden wir den Operator @(), der uns im nächsten Artikel benötigen wird – er ist sehr wichtig für das Hinzufügen anderer Arrays in ein Array (die Erstellung mehrdimensionaler Arrays), das Übergeben von Arrays an Funktionen als Argumente und ähnliche Aufgaben:
$test_array = @() #ein leeres Array erstellenBei der Initialisierung eines Arrays werden die Werte durch Kommas (Sonderoperator ,) aufgelistet:
$test_array = @(1, 2, 3, 4) #ein Array mit vier Elementen erstellen In den meisten Fällen kann der Operator @() weggelassen werden:
$test_array = 1, 2, 3, 4In diesem Fall wird ein Array mit einem Element folgendermaßen initialisiert:
$test_array = , 1Um auf die Elemente des Arrays zuzugreifen, wird ein nullbasierten ganzzahliger Index und der Indexpunkt (eckige Klammern) verwendet:
$test_array[0] = 1Es können mehrere Indizes durch Kommas angegeben werden, auch sich wiederholende:
$test_array = "eins", "zwei", "drei", "vier"
$test_array[0,1,2,3]
$test_array[1,1,3,3,0] 
Der Befehl .. (zwei Punkte — der Bereichsoperator) gibt ein Array von Ganzzahlen innerhalb eines bestimmten oberen und unteren Bereichs zurück. Zum Beispiel erzeugt der Ausdruck 1..4 ein Array mit vier Elementen @(1, 2, 3, 4), während der Ausdruck 8..5 ein Array @(8, 7, 6, 5) zurückgibt.

Mit dem Bereichsoperator kann ein Array initialisiert werden ($test_array = 1..4) oder ein Slice (Teilstück) erhalten werden, also eine Sequenz von Elementen eines Arrays mit Indizes aus einem anderen. Hierbei bedeutet die negative Zahl -1 das letzte Element des Arrays, -2 das vorletzte usw.
$test_array = "eins", "zwei", "drei", "vier"
$test_array[0..2]
$test_array[2..0]
$test_array[-1..0]
$test_array[-2..1]Bitte beachten Sie, dass die Werte des Ganzzahlarrays größer sein können als der maximale Indexwert des Arrays mit Daten. In diesem Fall werden alle Werte bis zum letzten zurückgegeben:
$test_array[0..100]Wenn versucht wird, auf ein einzelnes nicht existierendes Element des Arrays zuzugreifen, wird der Wert $null zurückgegeben.

In PowerShell können Arrays Elemente unterschiedlicher Typen enthalten oder stark typisiert sein:
$test_array = 1, 2, "test", 3, 4
for ([int]$i = 0; $i -lt $test_array.count; $i++)
{
Write-Host $test_array[$i]
}
Wo die Eigenschaft $test_array.count die Anzahl der Elemente im Array angibt.
Beispiel für die Erstellung eines streng typisierten Arrays:
[int[]]$test_array = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Hash-Tabellen
Ein weiterer grundlegender Variablentyp in PowerShell sind Hash-Tabellen, die auch als assoziative Arrays bezeichnet werden. HashTables ähneln JSON-Objekten und werden nach dem Prinzip Schlüssel-Wert aufgebaut. Im Gegensatz zu normalen Arrays erfolgt der Zugriff auf ihre Elemente über benannte Schlüssel, die Eigenschaften des Objekts sind (es kann auch der Indexoperator — eckige Klammern — verwendet werden).
Eine leere Hash-Tabelle wird mit dem Schlüsselzeichen @ und Operator-Klammern deklariert:
$test_hashtable = @{}Bei der Deklaration können gleich Schlüssel erstellt und Werte zugewiesen werden:
$test_hashtable = @{one="eins"; two="zwei"; three="drei"; "some key"="some value"}Um ein Element zu einer Hash-Tabelle hinzuzufügen, muss ein noch nicht existierender Schlüssel zugewiesen oder die Methode Add() verwendet werden. Wenn der Schlüssel, an den zugewiesen wird, bereits existiert, wird sein Wert geändert. Zum Entfernen eines Elements aus der Hash-Tabelle wird die Methode Remove() verwendet.
$test_hashtable."some key"
$test_hashtable["some key"]
$test_hashtable.Add("four", "vier")
$test_hashtable.five = "fünf"
$test_hashtable['five'] = "Wert ersetzen"
$test_hashtable.Remove("one") 
Variablen dieses Typs können als Argumente an Funktionen und Cmdlets übergeben werden – im nächsten Artikel werden wir untersuchen, wie dies geschieht, und einen weiteren ähnlichen Typ – PSCustomObject – betrachten.
Funktionen
Die PowerShell-Sprache bietet alle notwendigen Elemente für die prozedurale Programmierung, einschließlich Funktionen. Diese werden mit dem Schlüsselwort Function beschrieben, gefolgt vom Namen der Funktion und dem in geschweifte Klammern eingeschlossenen Funktionskörper. Um Argumente an die Funktion zu übergeben, können diese direkt nach dem Namen in runden Klammern angegeben werden.
function funktionsname (argument1, ..., argumentN)
{
funktionstext
}
Eine Funktion gibt immer ein Ergebnis zurück – dies ist ein Array der Ergebnisse aller ihrer Anweisungen, wenn es mehr als eine gibt. Bei einer Anweisung wird ein einzelner Wert des entsprechenden Typs zurückgegeben. Die Konstruktion return $value fügt ein Element mit dem Wert $value zum Ergebnisarray hinzu und beendet die Ausführung der Anweisungsliste, während eine leere Funktion $null zurückgibt.
Als Beispiel erstellen wir eine Funktion zur Berechnung der Quadratzahl:
function sqr ($number)
{
return $number * $number
}
Es ist zu beachten, dass innerhalb der Funktion alle vor ihrem Aufruf deklarierten Variablen verwendet werden können. Der Aufruf von Funktionen in PowerShell kann ungewohnt erscheinen: Argumente (sofern vorhanden) werden nicht in runde Klammern gesetzt und durch Leerzeichen getrennt.
sqr 2oder so:
sqr -number 2Wegen der Art der Argumentübergabe muss die Funktion manchmal in Klammern gesetzt werden:
function test_func ($n) {}
test_func -eq $null # Funktion wurde nicht aufgerufen
(test_func) -eq $null # Ergebnis des Ausdrucks — $true 
Bei der Beschreibung einer Funktion können Standardwerte für die Argumente festgelegt werden:
function func ($arg = Wert) {
# Körper der Funktion
}
Es gibt auch eine andere Syntax zur Beschreibung der Funktionsargumente, außerdem können Parameter aus dem Pipeline eingelesen werden – all dies wird im nächsten Artikel nützlich sein, wenn wir exportierbare Module und die Erstellung eigener Cmdlets betrachten.
Fehlerbehandlung
In PowerShell gibt es den Mechanismus Try…Catch…Finally, mit dem Ausnahmesituationen behandelt werden können. Im Try-Block wird der Code platziert, in dem ein Fehler auftreten kann, während der Catch-Block den entsprechend Fehlerbehandler enthält. Wenn kein Fehler auftritt, wird der Catch-Block nicht ausgeführt. Der Finally-Block wird nach dem Try-Block unabhängig davon ausgeführt, ob ein Fehler aufgetreten ist oder nicht, und es können mehrere Catch-Blöcke für verschiedene Arten von Ausnahmen vorhanden sein. Die Ausnahme selbst wird in einer standardmäßig nicht deklarierenden Variablen ($_) gespeichert und kann leicht extrahiert werden. Im folgenden Beispiel implementieren wir einen Schutz gegen die Eingabe ungültiger Werte:
try {
[int]$test = Read-Host "Geben Sie eine Zahl ein"
100 / $test
} catch {
Write-Warning "Ungültige Zahl"
Write-Host $_
}

Damit beenden wir die Einführung in die Grundlagen der Programmierung in PowerShell. In den nächsten Artikeln werden wir näher auf die Arbeit mit Variablen verschiedener Typen, Sammlungen, reguläre Ausdrücke, das Erstellen von Funktionen, Modulen und eigenen Cmdlets sowie die objektorientierte Programmierung eingehen.
Quelle: habr.com
