PowerShell má poměrně jednoduchou a přehlednou základní syntaxi, která je někdy narušena, ale většinově funguje. Základní syntaxí příkazu je:
Sloveso-PodstatnéJméno -parametr hodnota
Příkladem pak může být:
Get-Process -name explorer.exe
Jak jsem již uvedl v základní obecné syntaxi, podstatné jméno nemusí být pouze jedno, ale může jich být více zapsaných jako jedno slovo pomocí Calme zápisu (každé slovo začíná velkým písmenem). Příkladem takového zápisu může být přidání záznamu do DNS:
Add-DnsServerResourceRecordAAAA -Name "host24" -ZoneName "mojedomena.local"
-AllowUpdateAny -IPv6Address "192.168.1.24" -TimeToLive 01:00:00
Všechna běžně dostupná slovesa (vybrané moduly mohou užívat i další, ale vždy se rozsvítí varování při jejich importu) jsou dostupná následujícím příkazem:
Get-Verb
Úplný seznam uvádím níže:
Verb Group
---- -----
Add Common
Clear Common
Close Common
Copy Common
Enter Common
Exit Common
Find Common
Format Common
Get Common
Hide Common
Join Common
Lock Common
Move Common
New Common
Open Common
Optimize Common
Pop Common
Push Common
Redo Common
Remove Common
Rename Common
Reset Common
Resize Common
Search Common
Select Common
Set Common
Show Common
Skip Common
Split Common
Step Common
Switch Common
Undo Common
Unlock Common
Watch Common
Backup Data
Checkpoint Data
Compare Data
Compress Data
Convert Data
ConvertFrom Data
ConvertTo Data
Dismount Data
Edit Data
Expand Data
Export Data
Group Data
Import Data
Initialize Data
Limit Data
Merge Data
Mount Data
Out Data
Publish Data
Restore Data
Save Data
Sync Data
Unpublish Data
Update Data
Approve Lifecycle
Assert Lifecycle
Complete Lifecycle
Confirm Lifecycle
Deny Lifecycle
Disable Lifecycle
Enable Lifecycle
Install Lifecycle
Invoke Lifecycle
Register Lifecycle
Request Lifecycle
Restart Lifecycle
Resume Lifecycle
Start Lifecycle
Stop Lifecycle
Submit Lifecycle
Suspend Lifecycle
Uninstall Lifecycle
Unregister Lifecycle
Wait Lifecycle
Debug Diagnostic
Measure Diagnostic
Ping Diagnostic
Repair Diagnostic
Resolve Diagnostic
Test Diagnostic
Trace Diagnostic
Connect Communications
Disconnect Communications
Read Communications
Receive Communications
Send Communications
Write Communications
Block Security
Grant Security
Protect Security
Revoke Security
Unblock Security
Unprotect Security
Use Other
Sloveso vždy uvádí akci, kterou příkaz provede, proto vím, že příkazy začínající na Get, vždy slouží k nějakému získání dat, hodnot, ale nic nemění. Tato slovesa bychom měli užívat i ve vlastních funkcích a měli bychom se držet zásady, že funkce dělá to, co říká dané sloveso v jejím názvu.
Tato syntaxe je skvělá, protože kód je velmi dobře čitelný i pro úplného začátečníka, nebo člověka, který je daného jazyku neznalý. Její slabinou je zdlouhavost, proto se běžně užívají 2 věci, které zápis zkracují a urychlují:
- zkratky (aliasy) příkazů
- zápis pouze malými písmeny
Zápis pouze malými písmeny není žádný problém a mohu jej běžně doporučit užít i ve skriptech (dávkových souborech příkazů). PowerShell se pro interaktivní práci snaží zápis zkrátit tak, aby byl rychlý a efektivní. Aby toho dosáhl, má PowerShell tzv. aliasy, což jsou zkratky jednotlivých příkazů. Krom toho, že PowerShell má vestavěnou sadu Aliasů a každé rozšíření má volitelně sadu Aliasů pro své příkazy, může si uživatel defonovat také další svoje alisy. Seznam dostupných alisů získáme příkazem:
Get-Alias
Aliasy jde pohodlněji hledat pomocí definice (tedy uvedení příkazu, pro který chceme alis), např.:
get-alias -Definition Get-ChildItem
Aliasy mají pro správce systémů ještě jeden význam, snaží se PowerShell příkazy mapovat na CMD nebo BASH příkazy, které správci již dobře znají a běžně využívají. Výše uvedený příklad jsem nevybral náhodnou, pojďme se podívat, jaké jsou alisy pro Get-ChildItem:
get-alias -Definition Get-ChildItem
CommandType Name Version Source
----------- ---- ------- ------
Alias dir -> Get-ChildItem
Alias gci -> Get-ChildItem
Alias ls -> Get-ChildItem
Uvedené alisiy dir (pro Windows svět) a ls (pro Linuxový svět) jsou příkazy, které zná každý správce a sám tento příkaz využívám výhradně v podobě aliasu, byť poměrně často sáhnu po alisu gci. Další takový příklad je alias copy, který je zkratkou pro Copy-Item, případně Linuxáci budou preferovat aplias cp. Velmi často jsou užívané také alisy where a select, o kterých má člověk pocit, že jsou samotnými příkazy, protože málo kdy je vidět Whre-Object a Select-Object.
Pajpa – svislítko
Další běžnou součástí syntaxe v PowerShellu pro práci v terminálu i skriptech je pajpa. Pajpa má význam předání výstupu jednoho příkazu (výstupního objektu) jako vstupu do dalšího příkazu. Počet těchto předání, které zapášeme není nikterak omezen, ale pro přehlednost se využívá relativně nízký počet, obvykle jedno až tři. Příklad pak může být:
get-alias | where Source -eq "Microsoft.PowerShell.Utility" | Out-GridView
Výše uvedený příkaz vypíše aliasy příkazů, které jsou součástí modulu PowerShell Utility. Tento výpis se zobrazí v samostatném okně mřížky, která umožňuje prohledávání, filtrování a řazení výstupu.
Zapisování textu
Text, stejně jako ve většině programovacích jazyků, zadáváme v uvozovkách, ovšem v PowerShellu to není tak jednoduché, jak by se mohlo zdát. Když text zapíšeme do uvozovek (jak je známe v češtině), bude se vyhodnocovat dynamický obsah, viz následující příklad:
Write-Host "Dnes je $datum"
Dnes je 10.06.2023
Na proti tomu, když užiji apostrof (jednoduché uvozovky), dynamický obsah se nevyhodnocuje a budu mít vždy text přesně takový, jako jej mám zapsaný, viz níže:
Write-Host 'Dnes je $datum'
Dnes je $datum
Pokud chci, aby součástí textu byly uvozovky, např. nějaká citace, musím takový text uzavřít do jednoduchých uvozovek a bude platit, že dynamický obsah se nevyhodnocuje, protože české uvozovky jsou v tomto případě znakem textu, nikoliv vymezením textového řetěžce.
Proměnná
Nedílnou součástí psaní skriptů je využívání proměnných. Stejně jako ostatní skriptovací jazyky má i PowerShell dynamicky typované proměnné, tedy proměnné mění svůj datový typ v závislosti na svém obsahu. Jméno proměnné začíná vždy $, takže proměnnou s názvem cislo založíme následovně:
$cislo
Do proměnné se přiřazuje jako ve většině jazyků (alespoň těch, které vychází z C) pomocí symbolu rovnítko, hodnotu 2 tedy do proměnné cislo přiřadíme následovně:
$cislo = 2
Otázkou ovšem zůstává, jakého datového typu proměnná cislo je. K tomu, abychom tuto otázku zodpověděli si musíme uvědomit, že PowerShell je objektový jazyk vycházející z .NET, takže jeho objekty mají nějaké vlastnosti a funkce, ke kterým se dostaneme pomocí tečky. Datový typ naší proměnné zjistíme následovně
$cislo.gettype().name
Výsledkem bude typ Int32, tedy celé číslo. Co se stane, když do proměnné cislo zapíšeme hodnotu slovem?
$cislo = "dva"
$cislo.gettype().name
String
Nabízí se tedy otázka, mohu při psaní skriptu nějak zajistit, že v proměnné bude třeba text a nic jiného? Odpověď je ano, protože PowerShell umí na rozdíl od jiných dynamicky typovaných skriptovacích jazyků zafixovat typ proměnné, pomocí uvedení datového typu v hranatých závorkách před proměnnou, dokazuje to následující příklad.
PS C:\Users\petra> [string]$cislo = 2
PS C:\Users\petra> $cislo.gettype().name
String
PS C:\Users\petra> $cislo = "dva"
PS C:\Users\petra> $cislo.gettype().name
String
A co když není automatická konverze mezi dvěma typy možná?
PS C:\Users\petra> [int]$cislo = 2
PS C:\Users\petra> $cislo.gettype().name
Int32
PS C:\Users\petra> [int]$cislo = "2"
PS C:\Users\petra> $cislo.gettype().name
Int32
PS C:\Users\petra> [int]$cislo = "dva"
Cannot convert value "dva" to type "System.Int32". Error: "Vstupní řetězec nemá správný formát."
At line:1 char:1
+ [int]$cislo = "dva"
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
Jak je vidět, PowerShell vyhodí chybu a hodnotu do proměnné nezapíše. Zároveň však např. číslo zapsané číslicí ve formátu textu pozná a převede jej na číslo.
Proměnná Pajpy
Výchozí proměnná, proměnná pajpy či jinými názvy pojmenovávaný proměnná, která obsahuje objekt, jež je předávám mezi příkazy pomocí pajpy. Tato proměnná je součástí vlastního PowerShellu a má dvoje značení (od verze 3)
- $_ se obvykle značí a pomocí $_.<vlastnost> se dostanu k vlastnostem objektu, který mi přichází z pajpy
- $PSItem je plný názve pro tuto proměnnou, kterou nejčastěji zapisujeme jako $_
Další informace o proměnných najdete v dokumentaci PowerShellu a budeme se jim postupně věnovat v dalších článcích tak, jak je budeme potřebovat.
Proměnné prostředí Windows
Každý admin ví, že systém Windows má vlastní systémové proměnné. Tyto proměnné jsou v PowerShellu rovněž dostupné, ale jinak, nežli v CMD, nebo dialogu spustit, kde se uzavírají do symbolů procento. V PowerShellu mají zvláštní zápis, kde součástí jména proměnné je env:, viz příklad:
$Env:windir
Objekt
Opravdu velmi zjednodušeně jde říct, že v PowerShellu je objektem vše. Pokud se chci k něčemu chovat jako k objektu, není to nic těžkého.
- Proměnná rovnou využívá tečkové notace
- Příkaz zavřu do kulatých závorek a využívám tečkové notace
Přístup k vlastnostem objektu na proměnné jsme tu již viděli, jde o:
$cislo.gettype().name
Tento příklad je malinko zvláštní, protože na objektu proměnné $cislo využíváme metodu a na výstupním objektu této metody pak vlastnost. Jak by to bylo s tím, když chci objektově přistoupit k příkazu?
(Get-Date).AddHours(8)
Výše uvedený příkaz vrátí datum a čas, který bude platný za 8 hodin, přičemž využívá metodu objektu, který je vracen příkazem Get-Date.
Programátoři se ovšem nemusí bát, objekty je možné vytvářet pomocí tříd stejně, jako v jiných objektových jazycích, ale jde již o pokročilou věc, kterou IT profesionálové nejspíš potřebovat nebudou, proto si danou syntaxi najděte v dokumentaci.
Bloky
Již opravdu poslední částí obecné syntaxe jsou bloky, ať jde o funkce, větvení, skriptbloky, či sekce DSC. Všechny bloky uzavíráme do složených závorek, např.
try {New-Item -Path Z:\zaloha -name Dnesek -type "directory"} catch {write-host "Nezdařilo se"}