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 [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-Module
nebo 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ž GetNewClosure
vytvoří 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