Sdílet prostřednictvím


o_Funkcích

Krátký popis

Popisuje, jak vytvářet a používat funkce v PowerShellu.

Dlouhý popis

Funkce je seznam příkazů PowerShellu, které mají přiřazený název. Při spuštění funkce zadáte název funkce.

PowerShell definuje dva druhy funkcí:

  • Funkce je blok kódu, který lze volat podle názvu. Může přijímat vstup a vracet výstup. Funkce jsou definovány pomocí klíčového function slova.
  • Filtr je typ funkce navržené ke zpracování dat z kanálu. Filtry se definují pomocí klíčového filter slova.

Příkazy ve funkci můžete seskupit do jednoho ze čtyř různých předdefinovaných bloků příkazů. Tyto bloky příkazů jsou pojmenovány beginpomocí klíčových slov , process, enda clean. Pokud tato klíčová slova nepoužíváte, PowerShell umístí příkazy do příslušného bloku kódu.

Funkce můžou také fungovat jako rutiny. Můžete vytvořit funkci, která funguje stejně jako rutina bez použití C# programování. Další informace naleznete v tématu about_Functions_Advanced.

Důležitý

V souborech skriptů a modulech založených na skriptech musí být funkce před jejich zavolání definovány.

Syntaxe funkce

Funkce se definují pomocí následující syntaxe:

function [<scope:>]<name> {
  param([type]$Parameter1 [,[type]$Parameter2])
  dynamicparam {<statement list>}
  begin {<statement list>}
  process {<statement list>}
  end {<statement list>}
  clean {<statement list>}
}

Funkce obsahuje následující položky:

  • Klíčové slovo function
  • Obor (volitelné)
  • Název, který vyberete
  • Libovolný počet pojmenovaných parametrů (volitelné), včetně dynamických parametrů
  • Jeden nebo více příkazů PowerShellu uzavřených ve složených závorkách {}

Pokud v definici nepoužíváte jedno z klíčových slov (begin, processend, , clean), function PowerShell vloží příkazy do end bloku.

Další informace o klíčovém slově dynamicparam a dynamických parametrech ve funkcích naleznete v tématu about_Functions_Advanced_Parameters.

Funkce může být jednoduchá jako:

function Get-PowerShellProcess { Get-Process pwsh }

Jakmile je funkce definovaná, můžete ji použít jako předdefinované rutiny. Pokud chcete například volat nově definovanou funkci Get-PowerShellProcess:

Get-PowerShellProcess
 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
    110    78.72     172.39      10.62   10936   1 pwsh

Funkce může být také stejně složitá jako rutina.

Funkce můžou vracet hodnoty, které se dají zobrazit, přiřadit k proměnným nebo předat jiným funkcím nebo rutinám. K vrácení výstupu return můžete použít klíčové slovo. Klíčové slovo return nemá vliv ani nepotlačí jiný výstup vrácený z vaší funkce. Klíčové slovo return však ukončí funkci na daném řádku. Další informace najdete v tématu about_Return.

Syntaxe filtru

Účelem filter funkce je poskytnout krátký způsob definování funkce, která se spouští na každém objektu v kanálu.

Syntaxe filtru je následující:

filter [<scope:>]<name> {<statement list>}

Pro zjednodušení syntaxe funkcí filter vynecháte klíčové slovo bloku příkazu (begin, process, end, clean). PowerShell umístí příkazy do process bloku. Ve funkci filtru můžete použít libovolný z dalších bloků, ale záměrem bylo poskytnout zkrácený způsob definování funkce, která má jediný účel zpracování každého objektu v kanálu.

Následující filtr přebírá položky protokolu z kanálu a pak zobrazí buď celou položku, nebo pouze část zprávy položky:

filter Get-EventMessage ([switch]$MessageOnly) {
  if ($MessageOnly) { Out-Host -InputObject $_.Message }
  else { $_ }
}

Dá se použít takto:

Get-WinEvent -LogName System -MaxEvents 100 | Get-EventMessage -MessageOnly

Metody zpracování vstupu

Metody popsané v této části se označují jako metody zpracování vstupu. Pro funkce, tyto tři metody pojmenované beginpomocí , processa end bloky funkce. PowerShell 7.3 přidá metodu procesu bloku clean.

Ve svých funkcích nemusíte používat žádný z těchto bloků. Pokud pojmenovaný blok nepoužíváte, PowerShell vloží kód do end bloku funkce. Pokud ale použijete některý z těchto pojmenovaných bloků nebo definujete dynamicparam blok, musíte do pojmenovaného bloku vložit veškerý kód.

Následující příklad ukazuje osnovu funkce, která obsahuje begin blok pro jednorázové předběžné zpracování, process bloková data z kanálu a end blok pro jednorázové následné zpracování.

Function Test-ScriptCmdlet {
    [CmdletBinding(SupportsShouldProcess=$true)]
    param ($Parameter1)
    begin{}
    process{}
    end{}
}

begin

Tento blok slouží k poskytnutí volitelného jednorázového předběžného zpracování funkce. Modul runtime PowerShellu používá kód v tomto bloku jednou pro každou instanci funkce v kanálu.

process

Tento blok slouží k zajištění zpracování záznamu po záznamu pro funkci. Můžete použít blok process bez definování ostatních bloků. Počet process spuštění bloku závisí na tom, jak funkci používáte a jaký vstup funkce přijímá.

Automatická proměnná $_ nebo $PSItem obsahuje aktuální objekt v kanálu pro použití v bloku process. Automatická $input proměnná obsahuje enumerátor, který je k dispozici pouze pro funkce a bloky skriptů. Další informace naleznete v tématu about_Automatic_Variables.

  • Pokud je funkce vyvolána bez vstupu kanálu, PowerShell spustí process blok pouze jednou.
  • V rámci kanálu se blok process spustí jednou pro každý vstupní objekt, který dosáhne funkce.
  • Pokud je vstup kanálu, který dosáhne funkce, prázdný, process blok se nespustí.
    • Bloky begin, enda clean se stále spouštějí.

Důležitý

Pokud parametr funkce přijímá vstup kanálu a process blok není definovaný, zpracování záznamu po záznamu selže. V tomto případě se vaše funkce spustí jenom jednou bez ohledu na vstup.

end

Tento blok použijte k poskytnutí volitelného jednorázového následného zpracování funkce.

clean

Blok clean byl přidán v PowerShellu 7.3.

Blok clean je pohodlný způsob, jak uživatelům vyčistit prostředky, které se nachází v begin, processa end blocích. Je to sémanticky podobné bloku finally, který pokrývá všechny ostatní pojmenované bloky funkce skriptu nebo rutiny skriptu. Vyčištění prostředků se vynucuje pro následující scénáře:

  1. po dokončení provádění kanálu bez ukončení chyby
  2. při přerušení spuštění kanálu kvůli ukončovací chybě
  3. když je kanál zkrácen, například: Select-Object -First
  4. když je kanál zastaven pomocí Ctrl+c nebo StopProcessing()

Čistý blok zahodí všechny výstupy zapsané do datového proudu Success .

Opatrnost

Přidání bloku clean představuje zásadní změnu. Protože clean je analyzován jako klíčové slovo, brání uživatelům v přímém volání příkazu pojmenovaného clean jako první příkaz v bloku skriptu. Pravděpodobně to ale nebude problém. Příkaz můžete přesto vyvolat pomocí operátoru volání (& clean).

Jednoduché funkce

Funkce nemusí být složité, aby byly užitečné. Nejjednodušší funkce mají následující formát:

function <function-name> { statements }

Například následující funkce spustí PowerShell s možností Spustit jako správce.

function Start-PSAdmin { Start-Process PowerShell -Verb RunAs }

Pokud chcete funkci použít, zadejte: Start-PSAdmin

Chcete-li do funkce přidat příkazy, zadejte každý příkaz na samostatný řádek nebo k oddělení příkazů použijte středník (;).

Například následující funkce najde všechny soubory .jpg v adresářích aktuálního uživatele, které byly změněny po počátečním datu.

function Get-NewPicture {
  $start = Get-Date -Month 1 -Day 1 -Year 2010
  $allPics = Get-ChildItem -Path $Env:USERPROFILE\*.jpg -Recurse
  $allPics | Where-Object {$_.LastWriteTime -gt $Start}
}

Můžete vytvořit sadu nástrojů s užitečnými malými funkcemi. Přidejte tyto funkce do profilu PowerShellu, jak je popsáno v about_Profiles a dále v tomto článku.

Názvy funkcí

Funkci můžete přiřadit libovolný název. Pro funkce, které sdílíte s ostatními, byste ale měli dodržovat standardní pravidla pojmenování PowerShellu.

  • Názvy by se měly skládat z dvojice sloves-podstatné jméno, kde příkaz identifikuje akci, kterou funkce provede, a podstatné jméno identifikuje položku, na které rutina akci provede.
  • Názvy by měly používat schválené příkazy pro všechny příkazy PowerShellu. Použití schválených příkazů vytváří konzistenci pro uživatele.

Další informace o standardních příkazech PowerShellu najdete v tématu Schválené příkazy.

Funkce s parametry

Parametry můžete použít s funkcemi, včetně pojmenovaných parametrů, pozičních parametrů, parametrů přepínače a dynamických parametrů. Další informace odynamickýchch about_Functions_Advanced_Parametersch

Pojmenované parametry

Můžete definovat libovolný počet pojmenovaných parametrů. Můžete zahrnout výchozí hodnotu pro pojmenované parametry, jak je popsáno dále v tomto článku.

Parametry uvnitř složených závorek můžete definovat pomocí klíčového slova param, jak je znázorněno v následující ukázkové syntaxi:

function <name> {
  param ([type]$Parameter1 [,[type]$Parameter2])
  <statement list>
}

Můžete také definovat parametry mimo složené závorky bez klíčového slova param, jak je znázorněno v následující ukázkové syntaxi:

function <name> [([type]$Parameter1[,[type]$Parameter2])] {
  <statement list>
}

Například následující funkce používá alternativní syntaxi k definování dvou parametrů:

function Add-Numbers([int]$One, [int]$Two) {
    $One + $Two
}

I když je první metoda upřednostňovaná, mezi těmito dvěma metodami není žádný rozdíl.

Při spuštění funkce je hodnota, kterou zadáte pro parametr, přiřazena proměnné, která obsahuje název parametru. Hodnotu této proměnné lze použít ve funkci.

Následující příklad je funkce s názvem Get-SmallFiles. Tato funkce má parametr $Size. Funkce zobrazí všechny soubory, které jsou menší než hodnota parametru $Size, a vyloučí adresáře:

function Get-SmallFiles {
  param ($Size)
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

Ve funkci můžete použít proměnnou $Size, což je název definovaný pro parametr.

Pokud chcete použít tuto funkci, zadejte následující příkaz:

Get-SmallFiles -Size 50

Můžete také zadat hodnotu pojmenovaného parametru bez názvu parametru. Například následující příkaz vrátí stejný výsledek jako příkaz, který pojmenuje parametr Size:

Get-SmallFiles 50

Pokud chcete definovat výchozí hodnotu parametru, zadejte symbol rovná se a hodnotu za název parametru, jak je znázorněno v následující variantě Get-SmallFiles příkladu:

function Get-SmallFiles ($Size = 100) {
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

Pokud zadáte Get-SmallFiles bez hodnoty, funkce přiřadí 100 $size. Pokud zadáte hodnotu, použije funkce tuto hodnotu.

Volitelně můžete zadat krátký řetězec nápovědy popisující výchozí hodnotu parametru přidáním atributu PSDefaultValue k popisu parametru a zadáním vlastnosti Help vlastnosti PSDefaultValue. Pokud chcete poskytnout řetězec nápovědy, který popisuje výchozí hodnotu (100) parametru Size ve funkci Get-SmallFiles, přidejte atribut PSDefaultValue, jak je znázorněno v následujícím příkladu.

function Get-SmallFiles {
  param (
      [PSDefaultValue(Help = '100')]
      $Size = 100
  )
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

Další informace o třídě atributu PSDefaultValue naleznete v tématu PSDefaultValue – členy atributů.

Poziční parametry

Poziční parametr je parametr bez názvu parametru. PowerShell používá pořadí hodnot parametrů k přidružení každé hodnoty parametru k parametru ve funkci.

Při použití pozičních parametrů zadejte za název funkce jednu nebo více hodnot. Hodnoty pozičních parametrů jsou přiřazeny proměnné pole $args. Hodnota, která následuje za názvem funkce, je přiřazena první pozici v poli $args$args[0].

Následující funkce Get-Extension přidá příponu názvu souboru .txt k zadanému názvu souboru:

function Get-Extension {
  $name = $args[0] + ".txt"
  $name
}
Get-Extension myTextFile
myTextFile.txt

Parametry přepínače

Přepínač je parametr, který nevyžaduje hodnotu. Místo toho zadáte název funkce následovaný názvem parametru switch.

Pokud chcete definovat parametr přepínače, zadejte typ [switch] před název parametru, jak je znázorněno v následujícím příkladu:

function Switch-Item {
  param ([switch]$On)
  if ($On) { "Switch on" }
  else { "Switch off" }
}

Když za název funkce zadáte parametr přepínače On, zobrazí se Switch on. Bez parametru přepínače se zobrazí Switch off.

Switch-Item -On
Switch on
Switch-Item
Switch off

Při spuštění funkce můžete také přiřadit logickou hodnotu přepínače, jak je znázorněno v následujícím příkladu:

Switch-Item -On:$true
Switch on
Switch-Item -On:$false
Switch off

Předání hodnot parametrů pomocí splattingu

K reprezentaci parametrů příkazu můžete použít splatting. Tato funkce je představena ve Windows PowerShellu 3.0.

Tuto techniku použijte ve funkcích, které volají příkazy v relaci. Nemusíte deklarovat ani vyčíslovat parametry příkazu nebo měnit funkci při změně parametrů příkazu.

Následující ukázková funkce volá rutinu Get-Command. Příkaz používá @args k reprezentaci parametrů Get-Command.

function Get-MyCommand { Get-Command @args }

Při volání funkce Get-Command můžete použít všechny parametry Get-MyCommand. Parametry a hodnoty parametrů jsou předány příkazu pomocí @args.

Get-MyCommand -Name Get-ChildItem
CommandType     Name                ModuleName
-----------     ----                ----------
Cmdlet          Get-ChildItem       Microsoft.PowerShell.Management

Funkce @args používá automatický parametr $args, který představuje nedelarované parametry rutiny a hodnoty ze zbývajících argumentů.

Další informace naleznete v tématu about_Splatting.

Propojení objektů do funkcí

Každá funkce může přijímat vstupy z kanálu. Pomocí klíčových slov begin, process, enda clean můžete řídit, jak funkce zpracovává vstupy z kanálu. Následující ukázková syntaxe ukazuje tato klíčová slova:

Seznam příkazů process se spustí jednou pro každý objekt v kanálu. Zatímco je blok process spuštěný, každý objekt kanálu je přiřazen k $_ automatické proměnné, jeden objekt kanálu najednou.

Následující funkce používá klíčové slovo process. Funkce zobrazí hodnoty z kanálu:

function Get-Pipeline
{
  process {"The value is: $_"}
}

1, 2, 4 | Get-Pipeline
The value is: 1
The value is: 2
The value is: 4

Pokud chcete, aby funkce, která může přijímat vstup kanálu nebo vstup z parametru, musí process blok zpracovat oba případy. Například:

function Get-SumOfNumbers {
    param (
        [int[]]$Numbers
    )

    begin { $retValue = 0 }

    process {
        if ($MyInvocation.ExpectingInput) {
           "Pipeline input: $_"
           $retValue += $_
        } else {
           foreach ($n in $Numbers) {
               "Command line input: $n"
               $retValue += $n
           }
        }
    }

    end { "Sum = $retValue" }
}


PS> 1,2,3,4 | Get-SumOfNumbers
Pipeline input: 1
Pipeline input: 2
Pipeline input: 3
Pipeline input: 4
Sum = 10
PS> Get-SumOfNumbers 1,2,3,4
Command line input: 1
Command line input: 2
Command line input: 3
Command line input: 4
Sum = 10

Při použití funkce v kanálu jsou objekty předané funkci přiřazeny k $input automatické proměnné. Funkce spouští příkazy s blokem begin příkazu před tím, než všechny objekty pocházejí z kanálu. Funkce spouští příkazy s blokem end příkazu, pokud v kanálu nejsou žádné další objekty.

Následující příklad ukazuje automatickou $input proměnnou použitou begin v blokech příkazu a end int.

function Get-PipelineBeginEnd {
    begin   { "Begin: The input is $input" }
    end     { "End:   The input is $input" }
}

Při spuštění funkce se vstupem kanálu se zobrazí následující výsledky:

1, 2, 4 | Get-PipelineBeginEnd
Begin: The input is
End:   The input is 1 2 4

Když se příkaz begin spustí, funkce nemá vstup z kanálu. Příkaz end se spustí poté, co má funkce hodnoty.

Pokud má funkce klíčové slovo process, každý objekt v $input je odebrán z $input a přiřazen k $_. Následující příklad obsahuje seznam příkazů process:

function Get-PipelineInput
{
    process {"Processing:  $_ " }
    end     {"End:   The input is: $input" }
}

V tomto příkladu se každý objekt předá funkci do process seznamu příkazů. Příkazy process běží na každém objektu po jednom objektu. $input automatická proměnná je prázdná, když funkce dosáhne klíčového slova end.

1, 2, 4 | Get-PipelineInput
Processing:  1
Processing:  2
Processing:  4
End:   The input is:

Další informace najdete v tématu Použití výčtů

PowerShell 7.3 přidal blok clean. Blok clean je pohodlný způsob, jak uživatelům vyčistit prostředky vytvořené a používané v begin, processa end blocích. Je to sémanticky podobné bloku finally, který pokrývá všechny ostatní pojmenované bloky funkce skriptu nebo rutiny skriptu. Vyčištění prostředků se vynucuje pro následující scénáře:

  1. po dokončení provádění kanálu normálně bez ukončení chyby
  2. při přerušení spuštění kanálu kvůli ukončovací chybě
  3. když je kanál zkrácen, například: Select-Object -First
  4. když je kanál zastaven pomocí Ctrl+C nebo StopProcessing()

Opatrnost

Přidání bloku clean představuje zásadní změnu. Protože clean je analyzován jako klíčové slovo, brání uživatelům v přímém volání příkazu pojmenovaného clean jako první příkaz v bloku skriptu. Pravděpodobně to ale nebude problém. Příkaz lze přesto vyvolat pomocí operátoru volání (& clean).

Rozsah funkce

Funkce existuje v oboru, ve kterém ji vytvoříte.

Pokud je funkce součástí skriptu, je funkce k dispozici pro příkazy v rámci tohoto skriptu. Ve výchozím nastavení není funkce ve skriptu dostupná mimo tento skript.

Můžete zadat rozsah funkce. Například funkce se přidá do globálního oboru v následujícím příkladu:

function Global:Get-DependentSvs {
  Get-Service | Where-Object {$_.DependentServices}
}

Pokud je funkce v globálním oboru, můžete ji použít ve skriptech, ve funkcích a na příkazovém řádku.

Funkce vytvoří nový obor. Položky vytvořené ve funkci, například proměnné, existují pouze v oboru funkce.

Další informace najdete v tématu about_Scopes.

Vyhledání a správa funkcí pomocí Function: jednotky

Všechny funkce a filtry v PowerShellu se automaticky ukládají na jednotku Function:. Tato jednotka je vystavena poskytovatelem funkce PowerShellu.

Při odkazování na jednotku Function: zadejte dvojtečku za funkcestejně jako při odkazování na C nebo D jednotku počítače.

Následující příkaz zobrazí všechny funkce v aktuální relaci PowerShellu:

Get-ChildItem Function:

Příkazy ve funkci jsou uloženy jako skriptblock ve vlastnosti definice funkce. Pokud chcete například zobrazit příkazy ve funkci nápovědy, která je součástí PowerShellu, zadejte:

(Get-ChildItem Function:help).Definition

Můžete také použít následující syntaxi.

$Function:help

Další informace najdete v tématu about_Function_Provider.

Opakované použití funkcí v nových relacích

Když zadáte funkci na příkazovém řádku PowerShellu, stane se tato funkce součástí aktuální relace. Funkce je k dispozici až do ukončení relace.

Pokud chcete funkci používat ve všech relacích PowerShellu, přidejte tuto funkci do profilu PowerShellu. Další informace oprofilech about_Profilesch

Funkci můžete také uložit do souboru skriptu PowerShellu. Zadejte funkci do textového souboru a pak soubor uložte s příponou názvu souboru .ps1.

Vytvoření nápovědy pro funkce

Rutina Get-Help získá nápovědu pro funkce, rutiny, zprostředkovatele a skripty. Pokud chcete získat nápovědu pro funkci, zadejte Get-Help následovaný názvem funkce.

Pokud chcete například získat nápovědu pro funkci Get-MyDisks, zadejte:

Get-Help Get-MyDisks

Nápovědu pro funkci můžete napsat pomocí některé z těchto dvou metod:

  • Nápověda k Comment-Based pro funkce

    Vytvořte nápovědu pomocí speciálních klíčových slov v komentářích. Pokud chcete pro funkci vytvořit nápovědu založenou na komentářích, musí být komentáře umístěny na začátku, na konci nebo v těle funkce. Další informace o nápovědě založené na komentářích najdete v tématu about_Comment_Based_Help.

  • Nápověda k XML-Based pro funkce

    Pokud potřebujete lokalizovat obsah nápovědy do více jazyků, vyžaduje se nápověda založená na jazyce XML. Pokud chcete přidružit funkci k souboru nápovědy založenému na JAZYCE XML, použijte klíčové slovo nápovědy založené na .EXTERNALHELP komentáři. Bez tohoto klíčového slova Get-Help nemůže najít soubor nápovědy funkce a vrátí pouze automaticky vygenerovanou nápovědu.

    Další informace o klíčovém slově .EXTERNALHELP naleznete v tématu about_Comment_Based_Help. Další informace o nápovědě založené na jazyce XML naleznete v tématu How to Write Rutina Help.

Viz také