11. moduly

11,1 Úvod

Jak je uvedeno v § 3,14, modul je samostatně obsažená jednotka, která umožňuje rozdělení, uspořádání a abstrakci kódu prostředí PowerShell. 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 zachovány soukromým modulem nebo mohou být exportovány do relace, do které je modul importován.

Existují tři různé typy modulů: manifest, Script a Binary. 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 souboru místo .ps1 . Binární modul obsahuje typy tříd, které definují rutiny a zprostředkovatele. Na rozdíl od skriptovacích modulů jsou binární moduly zapisovány v kompilovaných jazycích. Tato specifikace nepokrývá binární moduly.

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

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

Při vytvoření relace PowerShellu se ve výchozím nastavení žádné moduly neimportují.

Po importu modulů se cesta pro hledání, která se používá k jejich vyhledání, definuje pomocí proměnné prostředí PSModulePath.

Následující rutiny se týkají modulů:

11,2 psaní modulu skriptu

Skriptovací modul je soubor skriptu. Vezměte v úvahu následující skriptovací modul:

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í jsou exportovány všechny názvy funkcí a pouze názvy funkcí. Když se ale rutina Export-ModuleMember použila k exportu všeho, exportují se jenom ty věci, které se exportují explicitně. Řadu příkazů a položek lze exportovat v jednom volání nebo v několika voláních této rutiny. taková volání jsou pro aktuální relaci kumulativní.

11,3 Instalace modulu skriptu

Skriptovací modul je definovaný v souboru skriptu a moduly se můžou ukládat do libovolného adresáře. Proměnná prostředí PSModulePath odkazuje na sadu adresářů, které mají být prohledány, pokud rutiny související s modulem hledají moduly, jejichž názvy neobsahují plně kvalifikovanou cestu. Je možné zadat další cesty pro vyhledávání. například

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

Všechny další přidané cesty mají vliv pouze na aktuální relaci.

Alternativně lze při importu modulu zadat úplnou cestu.

11,4 importování modulu skriptu

Aby bylo možné použít prostředky v modulu, je nutné tento modul naimportovat do aktuální relace pomocí rutiny Import-Module . Import-Module může omezit prostředky, které skutečně importují.

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ů prostřednictvím parametru Import-Module ArgumentList.

Vezměte v úvahu následující skript, který používá tyto funkce a aliasy definované v § 11,2:

Import-Module "E:\Scripts\Modules\PSTest _ teplota" – verbose

"0 degrees C is &quot; + (Convert-CentigradeToFahrenheit 0) + &quot; 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ů, pokud příkazy nebo položky v modulu mají stejné názvy jako příkazy nebo položky v relaci. Konflikt názvů má za následek, že název je skrytý nebo nahrazený. Parametr Import-Module předpony lze použít k zamezení konfliktům s pojmenováním. Také parametry alias, rutina, funkce a proměnné mohou omezit výběr příkazů, které mají být importovány, čímž se sníží pravděpodobnost konfliktu názvů.

I v případě, že je příkaz skrytý, lze jej spustit kvalifikováním jeho názvu s názvem modulu, ve kterém pochází. Například & M\F 100 vyvolá funkci F v modulu M a předá ji argument 100.

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

Diskuzi o rozsahu, ve kterém se vztahují k modulům, najdete v tématu § 3.5.6 .

11,5 odebrání modulu skriptu

Jeden nebo více modulů lze z relace odebrat prostřednictvím rutiny Remove-Module .

Odebráním modulu nedojde k odinstalaci modulu.

V modulu skriptu je možné určit kód, který se má provést před odebráním tohoto modulu, a to takto:

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

manifesty modulů 11,6

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 to dělá, má tento manifest stejný název jako modul, který popisuje, ale s .psd1 příponou souboru.

Manifest obsahuje omezené podmnožinu skriptu prostředí PowerShell, která vrací zatřiďovací tabulku 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ým souborem; může však obsahovat odkazy na datové typy, příkaz if a aritmetické operátory a porovnání. (Přiřazení, definice funkcí a smyčky nejsou povoleny.) Manifest má také přístup pro čtení k proměnným prostředí a může obsahovat volání rutiny Join-Path , takže lze vytvořit cesty.

Poznámka

Poznámka redaktora: 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ý klíč, který je vyžadován, je ModuleVersion.

Tady je příklad jednoduchého manifestu:

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

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

dynamické moduly 11,7

Dynamický modul je modul, který je vytvořen pomocí rutiny New-Module v paměti za běhu. není načten z disku. Uvažujte 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 $sb skriptu definuje obsah modulu, v tomto případě dvě funkce a dva aliasy těmto funkcím. Stejně jako u modulu na disku jsou ve výchozím nastavení exportovány jenom funkce, takže Export-ModuleMember rutiny existují k exportu obou funkcí i aliasů.

Po New-Module spuštění 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.

Podobně jako všechny moduly se členové dynamických modulů spouštějí v oboru privátního modulu, který je podřízeným globálním oborem. Get-Module Nelze získat dynamický modul, ale Get-Command může získat exportované členy.

Aby byl dynamický modul dostupný pro Get-Module , přesměrujte příkaz na Import-Module nebo vytvořte kanál objektu modulu, který New-Module vrátí, do Import-Module New-Module . Tato akce přidá dynamický modul do Get-Module seznamu, ale neuloží modul na disk nebo ho nastaví jako trvalý.

11,8 uzávěry

Dynamický modul lze použít k vytvoření uzávěru, funkce s připojenými daty. Uvažujte 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 1

$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 vracel další ID v sekvenci, Get-NextID jejíž počáteční hodnotu lze zadat. Nicméně je nutné podporovat více sekvencí, každý s vlastním $startValue a $nextID kontextem. To je dosaženo voláním metody [scriptblock]::GetNewClosure (§ 4.3.7).

Pokaždé, když se vytvoří GetNewClosure Nový uzávěr, vytvoří se nový dynamický modul a proměnné v oboru volajícího (v tomto případě blok skriptu obsahující přírůstek) se zkopírují do tohoto nového modulu. Aby bylo zajištěno, že nextId definovaný uvnitř nadřazené funkce (ale mimo blok skriptu), je nutné zadat explicitní skript: předpona oboru.

Blok skriptu samozřejmě 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