Dneska se trošku projedeme. Ale nebojte se, nemusíte vytáhnout paty z konzole, resp. ISE.

Chtěl bych vám dnes ukázat, jaké možnosti máme v PowerShellu při práci s cykly. Jelikož jsem v poslední době viděl několik špatných použití různých cyklovacích algoritmů.

Všechny následující příklady budu ukazovat na stejném příkazu. Mým cílem bude vypsat jména běžících procesů. Výsledek by měl být vždy stejný jako v následujícím případě

Get-Process | Select Name

For

Jedná se o základní příkaz cyklu, který existuje snad ve všech programovacích jazycích. Můžete jej použít v případě, kdy máte jasně daný počet opakování cyklu.

$procesy = Get-Process
for ($i = 0; $i -lt $procesy.Count; $i++)
{
    $procesy[$i].Name
}

Do proměnné $procesy jsme si uložili všechny procesy. Poté v cyklu forpoužijeme proměnnou $i, která nabývá hodnot od 0 do počtu procesů. Pozor na to, že pole jsou v PowerShellu číslována od nuly a proto je první člen z proměnné $procesy indexován nulou.

Předchozí kód můžeme tedy číst následovně: Ulož procesy do proměnné. Do proměnné $i ulož nulu. Vrať proces s indexem 0 a zobraz jeho jméno. Proměnnou $i zvyš o 1 (řečeno v $i++). Proveď znovu cyklus – vrať proces s indexem 1. Vše opakuj, až do počtu procesů uložených v proměnné $procesy.

While

Cyklus probíhá tak dlouho, dokud je splněna podmínka. Tedy

$j = 0
while ($j -le $procesy.Count)
{
    $procesy[$j].Name
    $j++
}

Předpokládáme proměnnou $procesy. Nastavíme $j na nulu. Podmínka nám říká, že dokud je $j menší nebo rovnou počtu procesů, procesy vypisujeme. Zároveň zvyšujeme $j o jednotku po každém výpisu.

Do

Tento příkaz se hodně často uveden jako „dvojče“ předchozího. Ukážeme si rovnou použití

$k = 0
do
{
    $procesy[$k].Name
    $k++
}
while ($k -le $procesy.Count)

Jak vidíte, rozdílem je použití podmínky na konci cyklu. U použití Do proběhne celý cyklus alespoň jednou. Což je rozdíl oproti použití předchozího příkazu while.

Příkaz Do lze použít ještě s klíčovým slovem until. V tomto případě je potřeba obrátit závěrečnou podmínku.

$k = 0
do
{
    $procesy[$k].Name
    $k++
}
until ($k -ge $procesy.Count)

Přečtěte si pozorně oba předchozí příklady a snažte se opravdu pochopit, jak fungují.

Všechny předchozí příklady jsem uvedl proto, že jsem dnes chtěl hlavně mluvit o asi nejpoužívanějším příkazu cyklu: foreach. Vzhledem k tomu, že jsem nedávno viděl špatné použití, rád bych se u něj zastavil na delší čas.

Foreach

Tento příkaz používejte vždy, když máte danou kolekci objektů a chcete je projít všechny. Typicky při použití Get* cmdletů a procházení výsledků. V našem případě tedy.

foreach ($p in $procesy)
{
    $p.Name
}

Zde vidíte úplně jiný přístup než v předchozích příkladech. Můžeme jej číst takto. Pro každý proces v kolekci uložených procesů (proměnná $procesy) vypiš jeho jméno.

Uvědomte si jednu důležitou vlastnost. V rámci foreachpracujete s proměnnou $p, nikoli $procesy! Pokud byste použili proměnnou $procesy uvnitř cyklu, dostanete nepředvídatelné výsledky.

Často můžete tento příklad vidět zapsaný i takto:

foreach ($p in Get-Process)
{
    $p.Name
}

Zde neukládáme mezi výsledky do proměnné, ale rovnou uvedeme Get-Process, který nám do cyklu foreachposílá jednotlivé procesy.

Pokud se podívám na své skripty, můžu říci, že v 99% případů používám foreach. Důvod je prostý – použití v IT Pro světě je ve většině případů typu: dej mi všechny položky a s každou z nich něco udělej. Ať se jedná o procesy, služby, soubory, virtuální počítače (VMM), kolekce (ConfigMgr), …

Závěrem

Pokud se chcete o zde zmíněných příkazech dozvědět více, podívejte se do nápovědy. Témata, která vás budou zajímat, jsou:

  • about_for
  • about_while
  • about_do
  • about_foreach

Jednou z věcí, která vám při používání pomůže, je ISE. Od verze 3 můžete použít tzv. Snippets. V ISE stiskněte Ctrl+J a poté napište jméno cyklu, který vás zajímá.

image

Poté, co stisknete klávesu Tab, ISE vám doplní strukturu příkazu. Na vás je již jen doplnit správné proměnné.

A ještě jedna poznámka z praxe. Od PowerShellu v3 máte možnost aktualizovat nápovědu. Rozhodně doporučuji tuto možnost využít. Není nic horšího, když po vás klient chce pomoci s modulem, o kterém jste nikdy neslyšeli  Nápověda je prvním zdrojem, po kterém vždy sahám. Jak jsem již psal několikrát – pokud znáte základy používání PowerShellu, není pro vás problém nasadit je na jakýkoli modul. Vždy je ale potřeba vědět, jak se chovají jednotlivé cmdlety. Pokud nemáte nápovědu, vše je o něco složitější.

Proto doporučuji pravidelně pouštět Update-Help.

image

Po doběhnutí celého procesu budete moci zkoumat cmdlety přímo z konzole.

David Moravec, MVP
Mainstream Technologies