Historisch gezien zijn de commandoregelhulpmiddelen in Unix-systemen beter ontwikkeld dan in Windows, maar met de komst van een nieuwe oplossing is de situatie veranderd.
Voor PowerShell kan men scripts schrijven in een interpreter-gebaseerde multi-paradigma-taal, waarin elementen van klassieke procedurele, objectgeoriënteerde en zelfs functionele programmering aanwezig zijn: voorwaardelijke sprongen, lussen, variabelen, arrays, hash-tabellen, klassen, foutafhandeling, evenals functies, cmdlets en pijpen. was gewijd aan de basisprincipes van werken in de omgeving, en nu bieden we de lezers een kleine handleiding voor programmeurs.
Inhoudsopgave:
Code kan in elke teksteditor worden geschreven of met behulp van een geïntegreerde ontwikkelomgeving — het eenvoudigste is om Windows PowerShell ISE te nemen uit de levering van serverbesturingssystemen van Microsoft. Dit is alleen nodig voor voldoende complexe scripts: korte commando's kunnen eenvoudiger interactief worden uitgevoerd.
Opmerkingen
Het gebruik van opmerkingen wordt beschouwd als een onderdeel van goede programmeerstijl, samen met de juiste inspringingen en spaties:
# Для строчных комментариев используется символ решетки — содержимое строки интерпретатор не обрабатывает.
<#
Так обозначаются начало и конец блочного комментария.
Заключенный между ними текст интерпретатор игнорирует.
#>
Variabelen en hun types
Variabelen in PowerShell zijn benoembare objecten. Hun namen kunnen het onderstrepingsymbool, letters en cijfers bevatten. Voor de naam wordt altijd het symbool $ gebruikt, en om een variabele te declareren, is het voldoende om de interpreter een geldig naam te geven:

Voor het initialiseren van een variabele (het toewijzen van een waarde) wordt de toewijzingsoperator (symbool =) gebruikt:
$test = 100Een variabele kan worden gedeclareerd met vermelding van haar type tussen vierkante haken (typecast-operator) vóór de naam of waarde:
[int]$test = 100
$test = [int]100Het is belangrijk te begrijpen dat variabelen in PowerShell volledige objecten (klassen) zijn met eigenschappen en methoden, waarvan de types zijn gebaseerd op de bestaande in .NET Core. Laten we de belangrijkste opsommen:
Type (klasse .NET)
Omschrijving
Voorbeeldcode
[string]
System.String
Unicode-string
$test = «test»
$test = ‘test’
[char]
System.Char
Unicode-teken (16 bits)
[char]$test = ‘c’
[bool]
System.Boolean
boolean type (logische waarde True of False)
[bool]$test = $true
[int]
System.Int32
tweeëndertig- bit geheel getal (32 bits)
[int]$test = 123456789
[long]
System.Int64
vierzestig-bits geheel getal (64 bits)
[long]$test = 12345678910
[single]
System.Single
floating point number van 32 bits
[single]$test = 12345.6789
[double]
System.Double
kommagetal met een lengte van 64 bits (8 bytes)
[double]$test = 123456789.101112
[decimal]
System.Decimal
kommagetal met een lengte van 128 bits (je moet d aan het einde toevoegen)
[decimal]$test = 12345.6789d
[DateTime]
System.DateTime
datum en tijd
$test = Get-Date
[array]
System.Object[]
array, waarbij de index van de elementen begint bij 0
$test_array = 1, 2, 'test', 3, 4
[hashtable]
System.Collections.Hashtable
hashtables — associatieve arrays met benoembare sleutels, opgebouwd volgens het principe: @{sleutel = 'waarde'}
$test_hashtable = @{one='één'; two='twee'; three='drie'}
PowerShell ondersteunt impliciete typeconversie; bovendien kan het type van een variabele tussentijds veranderen (bijvoorbeeld door gebruik te maken van de toewijzingsoperator), als het niet verplicht is gespecificeerd— in dit geval geeft de interpreter een foutmelding. Het type van de variabele uit het vorige voorbeeld kan worden bepaald door de methode GetType() aan te roepen:
$test.GetType().FullName 
Er zijn een aantal cmdlets voor het beheren van variabelen. Hun lijst wordt in een handige vorm weergegeven met de opdracht:
Get-Command -Noun Variable | ft -Property Name, Definition -AutoSize -Wrap 
Om de gedeclareerde variabelen en hun waarden te bekijken, kun je een speciale cmdlet gebruiken:
Get-Variable | moreDeze manier lijkt overbodig veel werk, met variabelen is het veel handiger om via operators te werken of rechtstreeks naar hun eigenschappen en methoden te verwijzen. Toch hebben cmdlets hun nut, omdat ze bepaalde extra parameters kunnen instellen. Het is belangrijk te begrijpen dat gebruikersvariabelen alleen binnen de huidige sessie zijn gedefinieerd. Nadat de console is gesloten of het script is beëindigd, worden ze verwijderd.
Systeemvariabelen
Naast door de gebruiker gedeclareerde variabelen zijn er ingebouwde (systeem) variabelen die niet worden verwijderd na het beëindigen van de huidige sessie. Ze worden in twee typen verdeeld, terwijl de gegevens over de status van PowerShell worden opgeslagen in automatische variabelen waaraan je zelf geen willekeurige waarden kunt toewijzen. Tot deze groep behoort bijvoorbeeld $PWD:
$PWD.Path 
Voor het opslaan van gebruikersinstellingen zijn voorkeurvariabelen nodig, waarvan de waarden kunnen worden gewijzigd. Bijvoorbeeld, met $ErrorActionPreference stel je de reactie van de opdrachtinterpreter in op het optreden van niet-kritische fouten.
Naast de operators en cmdlets voor het aanspreken van gedeclareerde variabelen, bestaat er een pseudo-opslagplaats Variable:. Hiermee kan men werken zoals met andere opslagplaatsen, waarbij de variabelen in dit geval lijken op objecten in een bestandssysteem:
Get-ChildItem Variable: | moreof
ls Variable: | more 
Zichtgebieden
Voor variabelen in PowerShell bestaat er het concept van scope. De globale scope (Global) is van toepassing op de gehele huidige sessie — dit omvat bijvoorbeeld systeemvariabelen. Lokale (Local) variabelen zijn alleen toegankelijk binnen de scope waarin ze zijn gedefinieerd: bijvoorbeeld binnen een functie. Er is ook een begrip van de script scope (Script), maar voor script commando's is deze in essentie lokaal. Standaard krijgen variabelen die worden gedeclareerd een lokale scope toe, en om dit te veranderen is een speciale constructie van de vorm nodig: $Global: variabele = waarde.
Bijvoorbeeld zo:
$Global:test = 100
Omgevingsvariabelen
Vanuit PowerShell is er ook een andere pseudo-opslagplaats Env:, waarmee je toegang kan krijgen tot omgevingsvariabelen. Bij het starten van de shell worden deze gekopieerd vanuit het bovenliggende proces (d.w.z. uit het programma dat de huidige sessie heeft geïnitieerd) en meestal komen hun oorspronkelijke waarden overeen met de waarden in het configuratiescherm. Om omgevingsvariabelen te bekijken, wordt de cmdlet Get-ChildItem of zijn aliassen gebruikt: ls en dir.
dir Env: 
Deze variabelen vertegenwoordigen reeksen bytes (of tekens, als je wilt), waarvan de interpretatie uitsluitend afhankelijk is van het programma dat ze gebruikt. Cmdlets met *-Variable werken niet met omgevingsvariabelen. Om toegang te krijgen tot deze, moet je de schijfprefix gebruiken:
$env:TEST = "Hello, World!" 
Rekenkundige operatoren en vergelijkingsoperatoren
In PowerShell zijn er de volgende wiskundige operatoren: + (optel), - (aftrek), * (vermenigvuldiging), / (delen) en % (modulus of restwaarde). Het resultaat van een wiskundige expressie wordt van links naar rechts berekend volgens de gebruikelijke volgorde van bewerkingen, en ronde haakjes worden gebruikt om delen van de expressie te groeperen. Spaties tussen operatoren worden genegeerd; ze worden alleen gebruikt om de leesbaarheid te verbeteren. De + operator voegt ook samen, terwijl de * operator strings herhaalt. Wanneer je probeert een nummer bij een string op te tellen, wordt het nummer omgezet in een string. Daarnaast zijn er in PowerShell vele vergelijkingsoperatoren die de overeenstemming tussen twee waarden controleren en logische True of False retourneren:
Operator
Omschrijving
Voorbeeldcode
-eq
Gelijk aan / Equals (vergelijkbaar met = of == in andere talen)
$test = 100
$test -eq 123
-ne
Niet gelijk aan / Not equal (vergelijkbaar met of !=)
$test = 100
$test -ne 123
-gt
Groter dan / Greater than (vergelijkbaar met >)
$test = 100
$test -gt 123
-ge
Groter dan of gelijk aan / Greater than or equal (vergelijkbaar met >=)
$test = 100
$test -ge 123
-lt
Kleiner dan / Less than (vergelijkbaar met <)
$test = 100
$test -lt 123
-le
Kleiner dan of gelijk aan / Less than or equal (vergelijkbaar met <=)
$test = 100
$test -le 123
Er zijn ook andere soortgelijke operatoren die bijvoorbeeld het vergelijken van strings met wildcards mogelijk maken of reguliere expressies gebruiken om overeenkomsten met een patroon te vinden. We zullen deze in detail bekijken in latere artikelen. De symbolen en = worden voor vergelijking niet gebruikt, omdat ze voor andere doeleinden zijn gereserveerd.
Toewijzingsoperatoren
Naast de meest voorkomende operator = zijn er ook andere toewijzingsoperatoren: +=, -=, *=, /= en %=. Ze wijzigen de waarde voordat deze wordt toegewezen. Evenzo werken de unitaire operatoren ++ en — die de waarde van een variabele verhogen of verlagen, ook als toewijzingsoperatoren.
Logische operatoren
Voor het beschrijven van complexe voorwaarden is alleen vergelijking niet voldoende. Elke logische expressie kan worden geschreven met behulp van de operatoren: -and, -or, -xor, -not en!.. Ze functioneren zoals in andere programmeertalen, en je kunt ronde haakjes gebruiken om de volgorde van berekening aan te geven:
("Test" -eq "Test") -and (100 -eq 100)
-not (123 -gt 321)
!(123 -gt 321)
Voorwaardelijke sprongen
De takoperatoren in PowerShell zijn standaard: IF (IF…ELSE, IF…ELSEIF…ELSE) en SWITCH. Laten we hun gebruik aan de hand van voorbeelden bekijken:
[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 of waarde is niet gedefinieerd"}
}
Lussen
In PowerShell zijn er verschillende soorten lussen: WHILE, DO WHILE, DO UNTIL, FOR en FOREACH.
Een preconditioneel lus werkt zolang het waar is:
[int]$test = 0
while ($test -lt 10) {
Write-Host $test
$test = $test + 1
}
Postconditionele lussen worden altijd ten minste één keer uitgevoerd, omdat de voorwaarde wordt gecontroleerd na de uitvoering van de iteratie. DO WHILE werkt zolang de voorwaarde waar is, terwijl DO UNTIL werkt zolang deze onwaar is:
[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)
Het aantal iteraties van de FOR-lus is van tevoren bekend:
for ([int]$test = 0; $test -lt 10; $test++) {
Write-Host $test
}
In de FOREACH-lus worden de elementen van een array of collectie (hash-tabel) doorlopen:
$test_collection = "item1", "item2", "item3"
foreach ($item in $test_collection)
{
Write-Host $item
}
Arrays
In PowerShell-variabelen worden niet alleen enkele objecten (nummer, string, enz.) opgeslagen, maar ook meerdere. De eenvoudigste vorm van dergelijke variabelen zijn arrays. Een array kan uit meerdere elementen bestaan, uit één element bestaan of leeg zijn, d.w.z. geen elementen bevatten. Voor de declaratie wordt de operator @() gebruikt, die we in het volgende artikel nodig zullen hebben – hij is zeer belangrijk voor het toevoegen van andere arrays aan een array (meerdimensionale arrays maken), het doorgeven van arrays aan functies als argument en dergelijke taken:
$test_array = @() #we maken een lege arrayBij de initialisatie van een array worden de waarden door een komma gescheiden (speciale operator ,):
$test_array = @(1, 2, 3, 4) # we maken een array van vier elementen In de meeste gevallen kan de operator @() worden overgeslagen:
$test_array = 1, 2, 3, 4In dit geval wordt een array van één element als volgt geinitialiseerd:
$test_array = , 1Om naar de elementen van een array te verwijzen, wordt een nulgebaseerde whole number index en de indexoperator (vierkante haken) gebruikt:
$test_array[0] = 1Meerdere indices kunnen door een komma worden opgegeven, inclusief herhalende:
$test_array = "één", "twee", "drie", "vier"
$test_array[0,1,2,3]
$test_array[1,1,3,3,0] 
Operator .. (twee punten - bereikoperator) retourneert een array van gehele getallen binnen een bepaalde boven- en ondergrens van een interval. Bijvoorbeeld, de expressie 1..4 levert een array op met vier elementen @(1, 2, 3, 4), terwijl de expressie 8..5 een array @(8, 7, 6, 5) retourneert.

Met de bereikoperator kan een array worden geïnitialiseerd ($test_array = 1..4) of kan een slice worden verkregen, dat wil zeggen een reeks elementen van de ene array met indices uit een andere. Hierbij staat het negatieve getal -1 voor het laatste element van de array, -2 voor het op één na laatste, enzovoorts.
$test_array = "een", "twee", "drie", "vier"
$test_array[0..2]
$test_array[2..0]
$test_array[-1..0]
$test_array[-2..1]Let op dat de waarden van de gehele array groter kunnen zijn dan de maximale waarde van de index van de gegevensarray. In dat geval worden alle waarden tot de laatste geretourneerd:
$test_array[0..100]Als geprobeerd wordt om naar een enkele niet-bestaande index van de array te verwijzen, wordt de waarde $null geretourneerd.

In PowerShell kunnen arrays elementen van verschillende types bevatten of strikt getypeerd zijn:
$test_array = 1, 2, "test", 3, 4
for ([int]$i = 0; $i -lt $test_array.count; $i++)
{
Write-Host $test_array[$i]
}
Waarbij de eigenschap $test_array.count het aantal elementen in de array aangeeft.
Voorbeeld van het maken van een strikt getypeerde array:
[int[]]$test_array = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Hash-tabellen
Een ander basistype variabelen in de programmeertaal PowerShell zijn hash-tabellen, die ook wel associatieve arrays worden genoemd. Hashtable lijkt op een JSON-object en wordt opgebouwd volgens het principe sleutel-waarde. In tegenstelling tot gewone arrays, wordt toegang tot hun elementen verkregen via benoemde sleutels, die de eigenschappen van het object zijn (de indexoperator - vierkante haken - kan ook worden gebruikt).
Een lege hash-tabel wordt gedeclareerd met de speciale symbolen @ en accolades:
$test_hashtable = @{}Bij de declaratie kunnen direct sleutels worden aangemaakt en aan deze sleutels waarden worden toegewezen:
$test_hashtable = @{one="een"; two="twee"; three="drie"; "some key"="some value"}Om een element aan de hash-tabel toe te voegen, moet je een nog niet bestaande sleutel toewijzen of de methode Add() gebruiken. Als een waarde wordt toegewezen aan een bestaande sleutel, verandert die waarde. Om een element uit de hash-tabel te verwijderen, wordt de methode Remove() gebruikt.
$test_hashtable."some key"
$test_hashtable["some key"]
$test_hashtable.Add("four", "vier")
$test_hashtable.five = "vijf"
$test_hashtable['five'] = "waarde vervangen"
$test_hashtable.Remove("one") 
Variabelen van dit type kunnen worden doorgegeven als argumenten aan functies en cmdlets — in het volgende artikel zullen we onderzoeken hoe dit werkt, en we zullen ook een andere vergelijkbare type bekijken: PSCustomObject.
Functies
De programmeertaal PowerShell bevat alle elementen die nodig zijn voor procedureel programmeren, inclusief functies. Voor hun beschrijving wordt het trefwoord Function gebruikt, gevolgd door de naam van de functie en de haakjes die de body omsluiten. Indien nodig kunnen argumenten voor de functie direct na de naam in de ronde haakjes worden opgegeven.
function naam-van-de-functie (argument1, ..., argumentN)
{
body-van-de-functie
}
Een functie geeft altijd een resultaat terug — dit is een array van resultaten van al zijn statements, als er meer dan één is. Als er slechts één statement is, wordt de overeenkomstige waarde van het betreffende type geretourneerd. De constructie return $value voegt een element met de waarde $value toe aan de array van resultaten en onderbreekt de uitvoering van de statement-lijst, terwijl een lege functie $null retourneert.
Laten we als voorbeeld een functie maken om een getal tot de tweede macht te verheffen:
function sqr ($number)
{
return $number * $number
}
Merk op dat in de body van de functie alle eerder gedeclareerde variabelen gebruikt kunnen worden, en dat het aanroepen van functies in PowerShell misschien ongebruikelijk lijkt: argumenten (indien aanwezig) worden niet in ronde haakjes geplaatst en worden gescheiden door spaties.
sqr 2of zo:
sqr -number 2Vanwege de manier waarop argumenten worden doorgegeven, moet de functie soms in haakjes worden geplaatst:
function test_func ($n) {}
test_func -eq $null # functie is niet aangeroepen
(test_func) -eq $null # resultaat van de expressie — $true 
Bij het beschrijven van een functie kunnen waarden voor argumenten als standaardwaarden worden toegewezen:
function func ($arg = value) {
#body van de functie
}
Er bestaat ook een andere syntaxis voor het beschrijven van functieargumenten, daarnaast kunnen parameters uit de pipeline worden gelezen — dit zal nuttig zijn in het volgende artikel, wanneer we geëxporteerde modules en het maken van eigen cmdlets zullen behandelen.
Foutafhandeling
In PowerShell is er een mechanisme Try…Catch…Finally dat uitzonderlijke situaties kan verwerken. In het Try-blok komt de code die een fout kan veroorzaken, en in het Catch-blok de handler daarvan. Als er geen fout is opgetreden, wordt het Catch-blok niet uitgevoerd. Het Finally-blok wordt altijd na het Try-blok uitgevoerd, ongeacht of er een fout is opgetreden, en er kunnen meerdere Catch-blokken zijn voor verschillende types uitzonderingen. De uitzondering zelf wordt opgeslagen in de niet-gedeclareerde standaardvariabele ($_) en kan eenvoudig worden opgehaald. In het onderstaande voorbeeld implementeren we een bescherming tegen onjuiste invoer:
try {
[int]$test = Read-Host "Voer een nummer in"
100 / $test
} catch {
Write-Warning "Onjuist nummer"
Write-Host $_
}

Hiermee sluiten we de basisprincipes van programmeren in PowerShell af. In de volgende artikelen zullen we dieper ingaan op het werken met variabelen van verschillende types, collecties, reguliere expressies, het creëren van functies, modules en eigen cmdlets, evenals object-georiënteerd programmeren.
Bron: habr.com
