11. Moduler

11.1 Introduktion

Som vi angav i 3.14 är en modul en självständig återanvändbar enhet som gör att PowerShell-kod kan partitioneras, organiseras och abstraheras. En modul kan innehålla en eller flera modulmedlemmar, som är kommandon (till exempel cmdlets och funktioner) och objekt (till exempel variabler och alias). Namnen på dessa medlemmar kan vara privata för modulen eller exporteras till den session som modulen importeras till.

Det finns tre olika modultyper: manifest, skript och binärfil. En manifestmodul är en fil som innehåller information om en modul och styr vissa aspekter av den modulens användning. En skriptmodul är en PowerShell-skriptfil med filnamnstillägget i .psm1 stället för .ps1. En binär modul innehåller klasstyper som definierar cmdlets och providers. Till skillnad från skriptmoduler skrivs binära moduler på kompilerade språk. Binära moduler omfattas inte av den här specifikationen.

En binär modul är en .NET-sammansättning (dvs. en DLL-fil) som kompilerades mot PowerShell-biblioteken.

Moduler kan kapslas; det vill säga en modul kan importera en annan modul. En modul som har associerade kapslade moduler är en rotmodul.

När en PowerShell-session skapas importeras inga moduler som standard.

När moduler importeras definieras den söksökväg som används för att hitta dem av miljövariabeln PSModulePath.

Följande cmdlets hanterar moduler:

11.2 Skriva en skriptmodul

En skriptmodul är en skriptfil. Överväg följande skriptmodul:

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

Den här modulen innehåller två funktioner som var och en har ett alias. Som standard exporteras alla funktionsnamn och endast funktionsnamn. Men när cmdleten Export-ModuleMember har använts för att exportera något exporteras endast de saker som exporteras explicit. En serie kommandon och objekt kan exporteras i ett anrop eller ett antal anrop till denna cmdlet. sådana anrop är kumulativa för den aktuella sessionen.

11.3 Installera en skriptmodul

En skriptmodul definieras i en skriptfil och moduler kan lagras i valfri katalog. Miljövariabeln PSModulePath pekar på en uppsättning kataloger som ska genomsökas när modulrelaterade cmdlets söker efter moduler vars namn inte innehåller en fullständigt kvalificerad sökväg. Ytterligare sökningssökvägar kan anges. till exempel

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

Eventuella ytterligare sökvägar som läggs till påverkar endast den aktuella sessionen.

Alternativt kan en fullständigt kvalificerad sökväg anges när en modul importeras.

11.4 Importera en skriptmodul

Innan resurserna i en modul kan användas måste modulen importeras till den aktuella sessionen med hjälp av cmdleten Import-Module. Import-Module kan begränsa de resurser som faktiskt importeras.

När en modul importeras körs dess skriptfil. Processen kan konfigureras genom att definiera en eller flera parametrar i skriptfilen och skicka motsvarande argument via parametern ArgumentList för Import-Module.

Överväg följande skript som använder dessa funktioner och alias som definierats i -11.2:

Import-Module "E:\Scripts\Modules\PSTestTemperature_" -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"

Att importera en modul orsakar en namnkonflikt när kommandon eller objekt i modulen har samma namn som kommandon eller objekt i sessionen. En namnkonflikt resulterar i att ett namn döljs eller ersätts. Prefixparametern för Import-Module kan användas för att undvika namnkonflikter. Dessutom kan parametrarna Alias, Cmdlet, Funktion och Variabel begränsa valet av kommandon som ska importeras, vilket minskar risken för namnkonflikt.

Även om ett kommando är dolt kan det köras genom att kvalificera dess namn med namnet på den modul som det kom från. Anropar till & M\F 100 exempel funktionen F i modul M och skickar argumentet 100.

När sessionen innehåller kommandon av samma typ med samma namn, till exempel två cmdlets med samma namn, körs som standard det senast tillagda kommandot.

I 3.5.6 finns en diskussion om omfånget som relaterar till moduler.

11.5 Ta bort en skriptmodul

En eller flera moduler kan tas bort från en session via cmdleten Remove-Module.

Modulen avinstalleras inte om du tar bort en modul.

I en skriptmodul är det möjligt att ange kod som ska köras innan modulen tas bort, enligt följande:

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

11.6 Modulmanifest

Enligt vad som anges i 11.1 är en manifestmodul en fil som innehåller information om en modul och kontrollerar vissa aspekter av den modulens användning.

En modul behöver inte ha ett motsvarande manifest, men om det gör det har manifestet samma namn som den modul som beskrivs, men med ett .psd1 filnamnstillägg.

Ett manifest innehåller en begränsad delmängd av PowerShell-skriptet, som returnerar en hash-tabell som innehåller en uppsättning nycklar. Dessa nycklar och deras värden anger manifestelementen för modulen. Det innebär att de beskriver innehållet och attributen för modulen, definierar eventuella krav och avgör hur komponenterna bearbetas.

I princip är ett manifest en datafil. Den kan dock innehålla referenser till datatyper, if-instruktionen och de aritmetiska operatorerna och jämförelseoperatorer. (Tilldelningar, funktionsdefinitioner och loopar tillåts inte.) Ett manifest har också läsbehörighet till miljövariabler och kan innehålla anrop till cmdleten Join-Path, så sökvägar kan konstrueras.

Anteckning

Redigerarens kommentar: Det ursprungliga dokumentet innehåller en lista över nycklar som tillåts i en modulmanifestfil. Listan är inaktuell och ofullständig. En fullständig lista över nycklar i ett modulmanifest finns i New-ModuleManifest.

Den enda nyckel som krävs är ModuleVersion.

Här är ett exempel på ett enkelt manifest:

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

Nyckel-GUID har ett string värde. Detta anger en globalt unik IDentifier (GUID) för modulen. GUID: t kan användas för att skilja mellan moduler med samma namn. Om du vill skapa ett nytt GUID anropar du metoden [guid]::NewGuid().

11.7 Dynamiska moduler

En dynamisk modul är en modul som skapas i minnet vid körning av cmdleten New-Module. Den läses inte in från disken. Se följande exempel:

$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

Skriptblocket definierar $sb innehållet i modulen, i det här fallet två funktioner och två alias för dessa funktioner. Precis som med en diskmodul exporteras endast funktioner som standard, Export-ModuleMember så cmdlets-anrop finns för att exportera både funktionerna och aliasen.

När New-Module körningar körs är de fyra namn som exporteras tillgängliga för användning i sessionen, vilket visas av anropen till Convert-CentigradeToFahrenheit och c2f.

Precis som alla moduler körs medlemmarna i dynamiska moduler i ett omfång för privata moduler som är underordnade det globala omfånget. Get-Module kan inte hämta en dynamisk modul, men Get-Command kan hämta de exporterade medlemmarna.

Om du vill göra en dynamisk modul tillgänglig för Get-Moduleska du skicka ett New-Module kommando Import-Moduletill , eller skicka modulobjektet som New-Module returnerar till Import-Module. Den här åtgärden lägger till den dynamiska modulen i Get-Module listan, men den sparar inte modulen på disk eller gör den beständig.

11.8 Stängningar

En dynamisk modul kan användas för att skapa en stängning, en funktion med anslutna data. Se följande exempel:

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

Avsikten här är att returnera Get-NextID nästa ID i en sekvens vars startvärde kan anges. Flera sekvenser måste dock stödjas, var och en med sin egen och $startValue sin kontext $nextID . Detta uppnås med anropet till metoden [scriptblock]::GetNewClosure (4.3.7).

Varje gång en GetNewClosureny stängning skapas av , skapas en ny dynamisk modul och variablerna i anroparens omfattning (i det här fallet skriptblocket som innehåller ökningen) kopieras till den nya modulen. För att säkerställa att nextId som definierats i den överordnade funktionen (men utanför skriptblocket) ökas krävs det explicita skriptet: scope prefix.

Skriptblocket behöver förstås inte vara en namngiven funktion. till exempel:

$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