Sdílet prostřednictvím


11. Moduly

Redakční poznámka

Důležitý

specifikace jazyka Windows PowerShell 3.0 byla publikována v prosinci 2012 a je založená na prostředí Windows PowerShell 3.0. Tato specifikace neodráží aktuální stav PowerShellu. Tato dokumentace se neplánuje aktualizovat tak, aby odrážela aktuální stav. Tato dokumentace je zde uvedena pro historické reference.

Dokument specifikace je k dispozici jako dokument aplikace Microsoft Word z webu Microsoft Download Center na adrese: https://www.microsoft.com/download/details.aspx?id=36389 Dokument aplikace Word byl převeden pro prezentaci zde na webu Microsoft Learn. Během převodu byly provedeny některé redakční změny tak, aby vyhovovaly formátování pro platformu Docs. Některé překlepy a menší chyby byly opraveny.

11.1 Úvod

Jak je uvedeno v §3.14, modul je samostatná opakovaně použitelná jednotka, která umožňuje rozdělit, uspořádat a abstrahovat kód PowerShellu. Modul může obsahovat jeden nebo více členů modulu, což jsou příkazy (například rutiny a funkce) a položky (například proměnné a aliasy). Názvy těchto členů mohou být v modulu soukromé nebo mohou být exportovány do relace, do které je modul importován.

Existují tři různé typy modulů : manifest, skript a binární soubor. Modul manifestu je soubor, který obsahuje informace o modulu a řídí určité aspekty použití tohoto modulu. Modul skriptu je soubor skriptu PowerShellu s příponou .psm1 místo .ps1. binární modul obsahuje třídy, které určují rutiny a zprostředkovatele. Na rozdíl od skriptových modulů jsou binární moduly napsané v kompilovaných jazycích. Tato specifikace neobsahuje binární moduly.

Binární modul je sestavení .NET (tj. dll), které bylo zkompilováno proti knihovnám PowerShellu.

Moduly mohou vnořit; to znamená, že jeden modul může importovat jiný modul. Modul, který má přidružené vnořené moduly, je kořenový modul.

Když se vytvoří relace PowerShellu, ve výchozím nastavení se neimportují žádné moduly.

Při importu modulů je cesta hledání použitá k jejich vyhledání definována proměnnou prostředí PSModulePath.

Následující cmdlety pracují s moduly:

  • Get-Module: Identifikuje moduly, které byly importovány, nebo je možné je importovat.
  • Import-Module: Přidá do aktuální relace jeden nebo více modulů (viz §11.4)
  • Export-ModuleMember: Identifikuje členy modulu, které se mají exportovat.
  • Odebrat modul: Odebere jeden nebo více modulů z aktuální relace (viz §11.5)
  • new-module : Vytvoří dynamický modul (viz §11.7)

11.2 Zápis modulu skriptu

Skriptovací modul je soubor skriptu. Zvažte následující modul skriptu:

function Convert-CentigradeToFahrenheit ([double]$tempC) {
    return ($tempC * (9.0 / 5.0)) + 32.0
}
New-Alias c2f Convert-CentigradeToFahrenheit

function Convert-FahrenheitToCentigrade ([double]$tempF) {
    return ($tempF - 32.0) * (5.0 / 9.0)
}
New-Alias f2c Convert-FahrenheitToCentigrade

Export-ModuleMember -Function Convert-CentigradeToFahrenheit
Export-ModuleMember -Function Convert-FahrenheitToCentigrade
Export-ModuleMember -Alias c2f, f2c

Tento modul obsahuje dvě funkce, z nichž každá má alias. Ve výchozím nastavení se exportují všechny názvy funkcí a pouze názvy funkcí. Jakmile se ale rutina Export-ModuleMember použije k exportu čehokoli, exportují se jenom ty věci, které se exportují explicitně. Řadu příkazů a položek je možné exportovat v jednom volání nebo několika voláních této rutiny; taková volání jsou kumulativní pro aktuální relaci.

11.3 Instalace modulu skriptu

Modul skriptu je definován v souboru skriptu a moduly lze uložit v libovolném adresáři. Proměnná prostředí PSModulePath odkazuje na sadu adresářů, které se mají prohledávat, když rutiny související s modulem hledají moduly, jejichž názvy neobsahují plně kvalifikovanou cestu. Lze zadat další cesty vyhledávání; například

$Env:PSModulepath = $Env:PSModulepath + ";<additional-path>"

Všechny přidané cesty ovlivňují pouze aktuální relaci.

Případně můžete zadat plně kvalifikovanou cestu při importu modulu.

11.4 Import modulu skriptu

Před použitím prostředků v modulu je nezbytné tento modul importovat do aktuální relace pomocí rutiny Import-Module. Import-Module může omezit prostředky, které skutečně importuje.

Při importu modulu se spustí jeho soubor skriptu. Tento proces lze nakonfigurovat definováním jednoho nebo více parametrů v souboru skriptu a předáním odpovídajících argumentů pomocí parametru ArgumentList Import-Module.

Zvažte následující skript, který používá tyto funkce a aliasy definované v §11.2:

Import-Module -Verbose "E:\Scripts\Modules\PSTest_Temperature"

"0 degrees C is " + (Convert-CentigradeToFahrenheit 0) + " degrees F"
"100 degrees C is " + (c2f 100) + " degrees F"
"32 degrees F is " + (Convert-FahrenheitToCentigrade 32) + " degrees C"
"212 degrees F is " + (f2c 212) + " degrees C"

Import modulu způsobí konflikt názvů, když příkazy nebo položky v modulu mají stejné názvy jako příkazy nebo položky v relaci. Konflikt názvů způsobí skrytí nebo nahrazení názvu. Parametr předpony Import-Module lze použít k zabránění konfliktům pojmenování. Také parametry Alias, Cmdlet, funkcea proměnné mohou omezit výběr importovaných příkazů, čímž se snižuje pravděpodobnost konfliktu názvů.

I když je příkaz skrytý, můžete ho spustit tak, že jeho název opravníte názvem modulu, ze kterého pochází. Například & M\F 100 vyvolá funkci F v modulu Ma předá ji argumentu 100.

Pokud relace obsahuje příkazy stejného typu se stejným názvem, například dvě rutiny se stejným názvem, ve výchozím nastavení spustí naposledy přidaný příkaz.

Viz §3.5.6 diskuzi o rozsahu, který souvisí s moduly.

11.5 Odebrání modulu skriptu

Jeden nebo více modulů lze z relace odebrat pomocí rutiny Remove-Module.

Odebráním modulu se modul neodinstaluje.

V modulu skriptu je možné určit kód, který se má provést před odebráním daného modulu, následujícím způsobem:

$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { *on-removal-code* }

11.6 Manifesty modulů

Jak je uvedeno v §11.1, modul manifestu je soubor, který obsahuje informace o modulu a řídí určité aspekty použití tohoto modulu.

Modul nemusí mít odpovídající manifest, ale pokud ano, má tento manifest stejný název jako modul, který popisuje, ale s příponou souboru .psd1.

Manifest obsahuje omezenou podmnožinu skriptu PowerShellu, která vrací hashtable obsahující sadu klíčů. Tyto klíče a jejich hodnoty určují prvky manifestu pro daný modul. To znamená, že popisují obsah a atributy modulu, definují všechny požadavky a určují, jak se komponenty zpracovávají.

Manifest je v podstatě datový soubor; může však obsahovat odkazy na datové typy, příkaz if a aritmetické a relační operátory. (Přiřazení, definice funkcí a smyčky nejsou povolená.) Manifest má také přístup pro čtení k proměnným prostředí a může obsahovat volání rutiny Join-Path, takže cesty lze vytvořit.

Poznámka

Poznámka editoru: Původní dokument obsahuje seznam klíčů povolených v souboru manifestu modulu. Tento seznam je zastaralý a neúplný. Úplný seznam klíčů v manifestu modulu najdete v tématu New-ModuleManifest.

Jediný požadovaný klíč je ModuleVersion.

Tady je příklad jednoduchého manifestu:

@{
ModuleVersion = '1.0'
Author = 'John Doe'
RequiredModules = @()
FunctionsToExport = 'Set*','Get*','Process*'
}

Klíč má hodnotu GUIDstring. Určuje globálně jedinečný identifikátor (GUID) pro modul. Identifikátor GUID lze použít k rozlišení mezi moduly se stejným názvem. Chcete-li vytvořit nový identifikátor GUID, zavolejte metodu [guid]::NewGuid().

11.7 Dynamické moduly

dynamický modul je modul vytvořený v paměti za běhu rutinou New-Module; nenačítá se z disku. Podívejte se na následující příklad:

$sb = {
    function Convert-CentigradeToFahrenheit ([double]$tempC) {
        return ($tempC * (9.0 / 5.0)) + 32.0
    }

    New-Alias c2f Convert-CentigradeToFahrenheit

    function Convert-FahrenheitToCentigrade ([double]$tempF) {
        return ($tempF - 32.0) * (5.0 / 9.0)
    }

    New-Alias f2c Convert-FahrenheitToCentigrade

    Export-ModuleMember -Function Convert-CentigradeToFahrenheit
    Export-ModuleMember -Function Convert-FahrenheitToCentigrade
    Export-ModuleMember -Alias c2f, f2c
}

New-Module -Name MyDynMod -ScriptBlock $sb
Convert-CentigradeToFahrenheit 100
c2f 100

Blok skriptu $sb definuje obsah modulu, v tomto případě dvě funkce a dva aliasy pro tyto funkce. Stejně jako u modulu na disku se ve výchozím nastavení exportují jenom funkce, takže Export-ModuleMember existují volání rutin pro export funkcí i aliasů.

Po spuštění New-Module jsou čtyři exportované názvy k dispozici pro použití v relaci, jak je znázorněno voláními Convert-CentigradeToFahrenheit a c2f.

Stejně jako všechny moduly se členové dynamických modulů spouštějí v soukromém rozsahu modulu, který je dceřiným globálním rozsahu. Get-Module nemůže získat dynamický modul, ale Get-Command může získat exportované členy.

Chcete-li zpřístupnit dynamický modul pro Get-Module, předejte New-Module příkaz k Import-Modulenebo předejte objekt modulu, který New-Module vrací, do Import-Module. Tato akce přidá dynamický modul do seznamu Get-Module, ale neuloží modul na disk nebo ho nastaví jako trvalý.

11.8 Uzavření

Dynamický modul lze použít k vytvoření uzávěru , což je funkce s připojenými daty. Podívejte se na následující příklad:

function Get-NextID ([int]$startValue = 1) {
    $nextID = $startValue
    {
        ($script:nextID++)
    }.GetNewClosure()
}

$v1 = Get-NextID      # get a scriptblock with $startValue of 0
& $v1                 # invoke Get-NextID getting back 1
& $v1                 # invoke Get-NextID getting back 2

$v2 = Get-NextID 100  # get a scriptblock with $startValue of 100
& $v2                 # invoke Get-NextID getting back 100
& $v2                 # invoke Get-NextID getting back 101

Záměrem je, aby Get-NextID vrátil další ID v posloupnosti, jejíž počáteční hodnotu lze zadat. Musí být však podporováno více sekvencí, z nichž každý má vlastní $startValue a $nextID kontext. Toho dosáhne volání metody [scriptblock]::GetNewClosure (§4.3.7).

Pokaždé, když GetNewClosurevytvoří nové uzavření, je vytvořen nový dynamický modul a proměnné v oboru volajícího (v tomto případě blok skriptu obsahující inkrementaci) jsou zkopírovány do tohoto nového modulu. Aby se zajistilo, že se nextId definované uvnitř nadřazené funkce (ale mimo blok skriptu) zvýší, je potřeba explicitní předpona rozsahu script:.

Samozřejmě, blok skriptu nemusí být pojmenovaná funkce; například:

$v3 = & {      # get a scriptblock with $startValue of 200
    param ([int]$startValue = 1)
    $nextID = $startValue
    {
        ($script:nextID++)
    }.GetNewClosure()
} 200

& $v3          # invoke script getting back 200
& $v3          # invoke script getting back 201