Condividi tramite


11. Moduli

Nota editoriale

Importante

La specifica del linguaggio Windows PowerShell 3.0 è stata pubblicata nel dicembre 2012 ed è basata su Windows PowerShell 3.0. Questa specifica non riflette lo stato corrente di PowerShell. Non è previsto l'aggiornamento di questa documentazione per riflettere lo stato corrente. Questa documentazione è presentata qui per riferimento cronologico.

Il documento di specifica è disponibile come documento di Microsoft Word dall'Area download Microsoft all'indirizzo: https://www.microsoft.com/download/details.aspx?id=36389. Quel documento Word è stato convertito per la presentazione su Microsoft Learn. Durante la conversione sono state apportate alcune modifiche editoriali per supportare la formattazione per la piattaforma Docs. Sono stati corretti alcuni errori di digitazioni e errori secondari.

11.1 Introduzione

Come indicato in §3.14, un modulo è un'unità riutilizzabile autonoma che consente il partizionamento, l'organizzazione e l'astrazione del codice di PowerShell. Un modulo può contenere uno o più membri del modulo , che sono comandi (ad esempio cmdlet e funzioni) e elementi (ad esempio variabili e alias). I nomi di questi membri possono essere mantenuti privati nel modulo oppure possono essere esportati nella sessione in cui il modulo viene importato.

Esistono tre tipi di modulo diversi: manifesto, script e binario. Un modulo manifesto è un file che contiene informazioni su un modulo e controlla alcuni aspetti dell'uso di tale modulo. Un modulo di script è un file script di PowerShell con un'estensione di file .psm1 invece di .ps1. Un modulo binario contiene tipi di classe che definiscono cmdlet e provider. A differenza dei moduli script, i moduli binari vengono scritti in linguaggi compilati. I moduli binari non sono coperti da questa specifica.

Un modulo binario è un assembly .NET (ad esempio una DLL) compilato in base alle librerie di PowerShell.

I moduli possono essere annidati; cioè, un modulo può importare un altro modulo. Un modulo associato a moduli annidati è un modulo radice .

Quando viene creata una sessione di PowerShell, per impostazione predefinita non vengono importati moduli.

Quando i moduli vengono importati, il percorso di ricerca usato per individuarli viene definito dalla variabile di ambiente PSModulePath.

I cmdlet seguenti gestiscono i moduli:

  • Get-Module: identifica i moduli che sono stati o possono essere importati
  • Import-Module : aggiunge uno o più moduli alla sessione corrente (vedere §11.4)
  • Export-ModuleMember: identifica i membri del modulo da esportare
  • remove-module: rimuove uno o più moduli dalla sessione corrente (vedere §11.5)
  • New-Module: crea un modulo dinamico (vedere §11.7)

11.2 Scrittura di un modulo di script

Un modulo script è un file di script. Si consideri il modulo di script seguente:

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

Questo modulo contiene due funzioni, ognuna delle quali ha un alias. Per impostazione predefinita, tutti i nomi delle funzioni e solo i nomi delle funzioni vengono esportati. Tuttavia, dopo aver usato il cmdlet Export-ModuleMember per esportare qualsiasi elemento, verranno esportati solo gli elementi esportati in modo esplicito. Una serie di comandi ed elementi può essere esportata in una chiamata o in una serie di chiamate a questo cmdlet; tali chiamate sono cumulative per la sessione corrente.

11.3 Installazione di un modulo script

Un modulo script viene definito in un file di script e i moduli possono essere archiviati in qualsiasi directory. La variabile di ambiente PSModulePath punta a un set di directory da cercare quando i cmdlet correlati ai moduli cercano moduli i cui nomi non includono un percorso completo. È possibile specificare percorsi di ricerca aggiuntivi; Per esempio

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

Tutti i percorsi aggiuntivi aggiunti influiscono solo sulla sessione corrente.

In alternativa, è possibile specificare un percorso completo quando viene importato un modulo.

11.4 Importazione di un modulo script

Prima di poter usare le risorse in un modulo, tale modulo deve essere importato nella sessione corrente usando il cmdlet Import-Module. Import-Module può limitare le risorse che effettivamente importa.

Quando un modulo viene importato, viene eseguito il relativo file di script. Tale processo può essere configurato definendo uno o più parametri nel file di script e passando argomenti corrispondenti tramite il parametro ArgumentList di Import-Module.

Si consideri lo script seguente che usa queste funzioni e alias definiti in §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"

L'importazione di un modulo causa un conflitto di nomi quando i comandi o gli elementi nel modulo hanno gli stessi nomi dei comandi o degli elementi nella sessione. Un conflitto di nomi comporta che un nome venga nascosto o sostituito. Il parametro Prefix di Import-Module può essere usato per evitare conflitti di denominazione. Inoltre, i parametri l'alias , il cmdlet , la funzione e la variabile possono limitare la selezione dei comandi da importare, riducendo così le probabilità di conflitti di denominazione.

Anche se un comando è nascosto, può essere eseguito qualificandone il nome con il nome del modulo in cui ha avuto origine. Ad esempio, & M\F 100 richiama la funzione F nel modulo Me le passa l'argomento 100.

Quando la sessione include comandi dello stesso tipo con lo stesso nome, ad esempio due cmdlet con lo stesso nome, per impostazione predefinita esegue il comando aggiunto più di recente.

Per una discussione sull'ambito in relazione ai moduli, vedere §3.5.6 di e.

11.5 Rimozione di un modulo script

È possibile rimuovere uno o più moduli da una sessione tramite il cmdlet Remove-Module.

La rimozione di un modulo non disinstalla il modulo.

In un modulo script è possibile specificare il codice che deve essere eseguito prima della rimozione del modulo, come indicato di seguito:

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

11.6 Manifesti del modulo

Come indicato in §11.1, un modulo manifesto è un file che contiene informazioni su un modulo e controlla alcuni aspetti dell'uso di tale modulo.

Un modulo non deve avere un manifesto corrispondente, ma in caso affermativo, tale manifesto ha lo stesso nome del modulo descritto, ma con un'estensione di file .psd1.

Un manifesto contiene un subset limitato di script di PowerShell, che restituisce una tabella Hash contenente un set di chiavi. Queste chiavi e i relativi valori specificano gli elementi manifesto per tale modulo. Ovvero descrivono il contenuto e gli attributi del modulo, definiscono eventuali prerequisiti e determinano come vengono elaborati i componenti.

Essenzialmente, un manifesto è un file di dati; Tuttavia, può contenere riferimenti ai tipi di dati, all'istruzione if e agli operatori aritmetici e di confronto. Le assegnazioni, le definizioni di funzione e i cicli non sono consentiti. Un manifesto ha anche accesso in lettura alle variabili di ambiente e può contenere chiamate al cmdlet Join-Path, in modo che i percorsi possano essere costruiti.

Nota

Nota dell'editor: il documento originale contiene un elenco di chiavi consentite in un file manifesto del modulo. L'elenco è obsoleto e incompleto. Per un elenco completo delle chiavi in un manifesto del modulo, vedere New-ModuleManifest.

L'unica chiave necessaria è ModuleVersion.

Di seguito è riportato un esempio di manifesto semplice:

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

La chiave GUID ha un valore string. Specifica un IDentifier univoco globale (GUID) per il modulo. Il GUID può essere usato per distinguere tra i moduli con lo stesso nome. Per creare un nuovo GUID, chiamare il metodo [guid]::NewGuid().

11.7 Moduli dinamici

Un modulo dinamico è un modulo creato in memoria in fase di esecuzione dal cmdlet New-Module; non viene caricato dal disco. Si consideri l'esempio seguente:

$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

Il blocco di script $sb definisce il contenuto del modulo, in questo caso due funzioni e due alias per tali funzioni. Come per un modulo su disco, solo le funzioni vengono esportate per impostazione predefinita, quindi Export-ModuleMember chiamate ai cmdlet esistono per esportare sia le funzioni che gli alias.

Una volta eseguita New-Module, i quattro nomi esportati sono disponibili per l'uso nella sessione, come illustrato dalle chiamate al Convert-CentigradeToFahrenheit e c2f.

Analogamente a tutti i moduli, i membri dei moduli dinamici vengono eseguiti in un contesto di modulo privato, che è figlio dell'ambito globale. Get-Module non può ottenere un modulo dinamico, ma Get-Command può ottenere i membri esportati.

Per rendere disponibile un modulo dinamico per Get-Module, inviare tramite pipe un comando New-Module a Import-Moduleo inviare tramite pipe l'oggetto modulo che New-Module restituisce, per Import-Module. Questa azione aggiunge il modulo dinamico all'elenco di Get-Module, ma non salva il modulo su disco o lo rende persistente.

11.8 Chiusura

È possibile usare un modulo dinamico per creare una chiusura , una funzione con dati collegati. Si consideri l'esempio seguente:

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

L'intento è che Get-NextID restituisca l'ID successivo in una sequenza con un valore iniziale specificabile. Tuttavia, è necessario supportare più sequenze, ognuna con il proprio contesto di $StartValue e $nextID. Questo risultato viene ottenuto dalla chiamata al metodo [scriptblock]::GetNewClosure (§4.3.7).

Ogni volta che viene creata una nuova chiusura da GetNewClosure, viene creato un nuovo modulo dinamico e le variabili nell'ambito del chiamante (in questo caso, il blocco di script contenente l'incremento) vengono copiate in questo nuovo modulo. Per assicurarsi che il nextId definito all'interno della funzione padre (ma all'esterno del blocco di script) venga incrementato, è necessario il prefisso esplicito Script: scope.

Naturalmente, il blocco di script non deve essere una funzione con un nome; per esempio:

$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