Percorso del modulo PowerShell: codice riutilizzabile senza copia-incolla

Lavorare con i moduli PowerShell è un elemento importante dell’automazione di PowerShell. Quando si inizia a imparare PowerShell, i primi passi di solito consistono nell’utilizzo di singoli comandi. Ciò porta a costruire script che a loro volta portano a costruire funzioni.

Utilizzando le funzioni, è possibile rendere gli script più modulari. Ciò consente di utilizzare lo stesso codice in molti luoghi senza copiare e incollare il codice ovunque. L’utilizzo delle funzioni consente di dedicare meno tempo a modificare lo stesso codice ovunque venga utilizzato. Invece, è possibile lavorare per migliorare il codice in un unico punto.

Per portare le funzioni al livello successivo, è possibile combinare queste funzioni in un modulo.

A module is a collection of functions in a text file with a psm1 extension. There are some optional additions, such as a module manifest and comment-based or external help that may also be included. These will be covered later on.

Prerequisiti

I’ll be using Windows PowerShell 5.1 in this article. If you’re using an older version or PowerShell Core, your mileage may vary as to results you see.

Interazione con i moduli

Dopo aver aperto una sessione PowerShell per la prima volta, si inizierà con due moduli. Il primo è Microsoft.PowerShell.Utility che contiene molte funzioni di base di PowerShell che si utilizzano già. L’altro modulo è PSReadline. È possibile visualizzare questi moduli iniziali utilizzando il comando Get-Module.

Listing modules with Get-Module

Detto questo, questa non è una lista completa di tutti i moduli disponibili. Da PowerShell 3, i moduli installati verranno importati solo se necessario. Se si sta eseguendo una versione più vecchia di PowerShell, sarà necessario utilizzare il comando Import-Module per importare prima il modulo prima di utilizzare qualsiasi comando.

Ci sono momenti in cui si desidera comunque utilizzare Import-Module anche nelle versioni successive. Se si desidera importare un modulo dopo che è già stato installato, è possibile utilizzare Import-Module in questo modo:

Importing modules with Import-Module

Mentre Get-Module mostrerà tutti i moduli che sono stati importati, non vedrai i moduli che non sono ancora stati importati. Puoi quindi utilizzare il parametro ListAvailable per mostrare tutti gli altri moduli disponibili.

Listing all available modules with Get-Module -ListAvailable

Non tutti i comandi vengono mostrati per impostazione predefinita

La proprietà ExportedCommands contiene un elenco di tutti i comandi disponibili che sono esportati dal modulo. Potresti vedere alcune differenze tra questo elenco e ciò che è nel file del modulo. I comandi esportati sono una funzionalità integrata nel manifesto del modulo che consente all’autore di lasciare una funzione nascosta. Gli autori dei moduli possono anche utilizzare il cmdlet Export-ModuleMember, ma questo esula dall’ambito di questo articolo.

Gli autori dei moduli possono voler nascondere una funzione perché è destinata a supportare altre funzioni, non a essere utilizzata dall’utente. Per nascondere una funzione, l’autore escluderebbe questa dal’array FunctionsToExport nel manifesto. Qui puoi vedere una visualizzazione dettagliata della proprietà ExportedCommands.

Viewing exported commands

Importazione dei moduli

Ci sono molti modi per iniziare a utilizzare i moduli. È possibile importare manualmente il modulo utilizzando il percorso dei file del modulo. Ciò consente di testare e aggiornare il modulo senza dover fare molto lavoro. Tuttavia, ciò non consente molta portabilità, poiché è necessario utilizzare il percorso esatto del modulo. PowerShell non importerà automaticamente i moduli non presenti nella variabile $env:PSModulePath.

Importazione selettiva dei comandi

È possibile utilizzare Import-Module per importare solo funzioni specifiche anziché l’intero modulo utilizzando il parametro Function. Ciò può risparmiare tempo durante l’importazione di moduli da sistemi remoti, come i moduli di Office 365.

Tutti i moduli utente

I moduli installati per tutti gli utenti vengono inseriti in C:\Program Files\WindowsPowerShell\Modules. Questa directory contiene molti moduli predefiniti, inclusi eventuali moduli installati utilizzando Install-Module con la portata predefinita AllUsers.

Moduli utente corrente

Se si sta installando un modulo ma si desidera che solo un singolo utente lo utilizzi, esiste una portata CurrentUser. Ciò inserisce i file del modulo nella cartella Documenti nella cartella C:\Users\\Documents\WindowsPowerShell\Modules. Questo può essere utile in un ambiente in cui si utilizza la ridirezione delle cartelle con la cartella Documenti.

In questo caso, è possibile installare un modulo su un computer e utilizzarlo su un altro poiché entrambi condivideranno la stessa cartella Documenti.

Moduli di sistema

Per completezza, c’è anche una directory dei moduli in C:\Windows\System32\WindowsPowerShell\1.0\Modules. Anche se tecnicamente, un modulo posizionato in questo percorso verrebbe importato come gli altri percorsi, non è consigliato in quanto è riservato ai moduli di sistema di Microsoft.

Il nome è importante

Puoi posizionare manualmente il tuo modulo in uno di questi percorsi per renderlo disponibile di default con una nuova sessione, ma devi assicurarti di seguire la denominazione richiesta per i moduli. La cartella in cui vengono posizionati i file del modulo deve avere lo stesso nome del file psm1 del modulo e del manifesto del modulo psd1, se presente.

Utilizzando Get-Module -ListAvailable che avevamo menzionato in precedenza, si fanno riferimento a questi percorsi. È possibile visualizzare tutti i percorsi dei moduli utilizzando $env:PSModulePath -Split ';'. Potresti notare altri percorsi nell’elenco rispetto a quelli mostrati qui. Molti programmi aggiungono i propri percorsi dei moduli durante l’installazione. Uno degli esempi di ciò è SQL, che ha i suoi moduli inclusi nei propri percorsi dei moduli.

Viewing module paths with $env:PSModulePath

Ci sono anche alcuni moduli che vengono installati con un processo diverso. Uno degli esempi più significativi è il modulo ActiveDirectory. Da Windows 7 fino a Windows 10 1803, è possibile installarlo con l’installatore Remote Server Administration Tools (RSAT).

Nelle versioni più recenti di Windows 10 (1809+), è disponibile solo tramite Features On Demand. L’installazione di RSAT installa i moduli ActiveDirectory e molti altri che vengono utilizzati per amministrare altre funzionalità di Windows. Nei sistemi operativi Windows Server, questi moduli vengono installati tramite Server Manager.

Importazione di moduli remoti (Remoting implicito)

In alcuni casi non è pratico avere un modulo in esecuzione localmente. È invece meglio connettersi a un dispositivo remoto e importare un modulo installato su di esso. Quando lo fai, i comandi vengono effettivamente eseguiti sulla macchina remota. Questo viene spesso utilizzato con i moduli di Office 365 di Microsoft. Molti di essi si connettono a un server di Office 365 che quindi importa un modulo. Quando esegui uno qualsiasi dei comandi, vengono eseguiti sul server remoto e quindi l’output viene inviato alla tua sessione.

Un altro uso dell’importazione di moduli remoti è quando non hai il modulo installato localmente. Questo è ciò che otterresti se non avessi installato il modulo ActiveDirectory, ma cercassi di importarlo.

Module not installed

Per importare un modulo remoto, devi prima creare una PSSession. Puoi utilizzare il comando New-PSSession per creare la sessione. Successivamente, importeresti il modulo disponibile sul dispositivo remoto utilizzando il parametro PSSession con il comando Import-Module.

PS51> $AdminServer = New-PSSession -ComputerName $AdminServerName -Credential (Get-Credential)
PS51> Import-Module -Name ActiveDirectory -PSSession $AdminServer -Prefix 'Rmt'

L’utilizzo di questo metodo di importazione di moduli remoti consente una maggiore velocità di esecuzione del codice in un ambiente distribuito. Ad esempio, se stai lavorando dal tuo computer, ma i server su cui stai lavorando si trovano negli Stati Uniti, potrebbe richiedere significativamente più tempo eseguire determinati comandi localmente sui server. Al contrario, eseguire i comandi su un server e inviare l’output alla sessione locale è molto più veloce.

Aggiunta di un prefisso al modulo

Puoi anche aggiungere un prefisso alle funzioni importate dalla macchina remota. Questa opzione è disponibile durante l’importazione dei moduli locali, ma viene raramente utilizzata al di fuori dei casi in cui si vogliono testare diverse versioni di un modulo contemporaneamente.

Se esegui il comando di importazione sopra riportato, ecco cosa vedresti quando guardi i comandi:

Viewing all available commands in a module

In questo caso, puoi utilizzare un prefisso per indicare che si tratta di un modulo remoto. Questo può essere utilizzato nei casi in cui si sta importando un modulo disponibile anche localmente. L’aggiunta del prefisso riduce la confusione su dove viene eseguito il codice.

Rimozione dei moduli

Puoi anche rimuovere un modulo dalla sessione corrente senza utilizzare Remove-Module. Questo rimuove un modulo dalla sessione locale senza eliminare i file del modulo. Puoi utilizzare questa opzione nel caso in cui stavi utilizzando una sessione remota per utilizzare un modulo. Potresti utilizzare Remove-Module per pulire la sessione e quindi disconnettere la sessione remota.

Removing a module from the session

Un altro utilizzo di Remove-Module è se stai apportando modifiche a un modulo e non desideri avviare una nuova sessione di PowerShell. In questo caso, utilizzeresti Remove-Module seguito da Import-Module per ricaricarlo nella sessione. In alternativa, puoi utilizzare il parametro Force con Import-Module. Questo completerà lo scarico e il ricaricamento del modulo per te.

Cosa compone un modulo di PowerShell

A module can consist of one or more files. To meet the minimum requirements for a module, you must have a module file. This can be a PSM1 file or any other module file such as a binary module file. To build upon that, your psm1 should have functions defined in it, or it will not be much use to anyone.

Sebbene non vi siano requisiti riguardo all’aspetto o alla funzionalità delle funzioni, ci sono alcune linee guida. Di solito è preferibile avere tutte le funzioni in un modulo incentrato sullo stesso concetto.

I Moduli Contengono Funzioni Affini

Ad esempio, il modulo ActiveDirectory include solo funzioni che interagiscono in qualche modo con Active Directory. Di solito i nomi delle funzioni contengono anche un prefisso. Riprendendo l’esempio del modulo ActiveDirectory, tutti i sostantivi nei nomi delle funzioni iniziano con AD.

L’utilizzo di queste linee guida aiuta nella scopribilità delle funzioni. Immagina di aver appena importato questo nuovo modulo e vuoi sfogliare le funzioni. Questo è molto più facile da fare se tutte le funzioni hanno una struttura di nome simile. Sebbene tu possa vedere frequentemente moduli che iniziano con PS, questo prefisso è ufficialmente riservato solo ai moduli Microsoft. Probabilmente non causerai problemi se utilizzi PS all’inizio del tuo modulo, ma potresti creare un conflitto con un altro nome di modulo.

Utilizzando queste linee guida, se avessi un insieme di funzioni che riguardano tutte l’interazione con il registro, potresti avere qualcosa del genere:

function Get-ATARegistryKey {...}

function Set-ATARegistryKey {...}

Manifesti dei Moduli

Per ampliare il file di modulo di testo, è possibile includere anche un manifesto del modulo. Questi file hanno estensione PSD1 e contengono metadati sul modulo. Qui è possibile includere informazioni sull’autore, descrizione del modulo, altri moduli richiesti e molti altri attributi. Per pubblicare su un repository, è necessario popolare i campi Author e Description.

Ecco un esempio di un manifesto che potremmo avere per il nostro modulo di registro:

#Manifest del modulo per il modulo 'ATARegistry'
#Generato da: Tyler
#Generato il: 8/11/2019
@{
	#File del modulo di script o del modulo binario associato a questo manifest
	RootModule = 'ATARegistry'
	#Numero di versione di questo modulo
	ModuleVersion = '1.0'
	#Edizioni PSEdition supportate
	#CompatiblePSEditions = @()
	#ID utilizzato per identificare univocamente questo modulo
	GUID = 'fef619fa-016d-4b11-a09d-b222e094de3e'
	#Autore di questo modulo
	Author = 'Tyler Muir'
	#Azienda o fornitore di questo modulo
	CompanyName = 'Adam the Automator'
	#Dichiarazione di copyright per questo modulo
	Copyright = '(c) 2019 tyler. All rights reserved.'
	#Descrizione della funzionalità fornita da questo modulo
	Description = 'This is a test module.'
	#Versione minima del motore Windows PowerShell richiesta da questo modulo
	#PowerShellVersion = ''
	#Nome dell'host Windows PowerShell richiesto da questo modulo
	#PowerShellHostName = ''
	#Versione minima dell'host Windows PowerShell richiesta da questo modulo
	#PowerShellHostVersion = ''
	#Versione minima del framework .NET di Microsoft richiesta da questo modulo. Questo prerequisito è valido solo per l'edizione PowerShell Desktop.
	#DotNetFrameworkVersion = ''
	#Versione minima del runtime del linguaggio comune (CLR) richiesta da questo modulo. Questo prerequisito è valido solo per l'edizione PowerShell Desktop.
	#CLRVersion = ''
	#Architettura del processore (None, X86, Amd64) richiesta da questo modulo
	#ProcessorArchitecture = ''
	#Moduli che devono essere importati nell'ambiente globale prima di importare questo modulo
	#RequiredModules = @()
	#Assembly che devono essere caricati prima di importare questo modulo
	#RequiredAssemblies = @()
	#File di script (.ps1) che vengono eseguiti nell'ambiente del chiamante prima di importare questo modulo
	#ScriptsToProcess = @()
	#File di tipo (.ps1xml) da caricare durante l'importazione di questo modulo
	#TypesToProcess = @()
	#File di formato (.ps1xml) da caricare durante l'importazione di questo modulo
	#FormatsToProcess = @()
	#Moduli da importare come moduli nidificati del modulo specificato in RootModule/ModuleToProcess
	#NestedModules = @()
	#Funzioni da esportare da questo modulo, per prestazioni ottimali, non utilizzare caratteri jolly e non eliminare la voce, utilizzare un array vuoto se non ci sono funzioni da esportare
	FunctionsToExport = @('Get-RegistryKey','Set-RegistryKey')
	#Cmdlet da esportare da questo modulo, per prestazioni ottimali, non utilizzare caratteri jolly e non eliminare la voce, utilizzare un array vuoto se non ci sono cmdlet da esportare
	CmdletsToExport = @()
	#Variabili da esportare da questo moduloVariablesToExport = '*'
	#Alias da esportare da questo modulo, per prestazioni ottimali, non utilizzare caratteri jolly e non eliminare la voce, utilizzare un array vuoto se non ci sono alias da esportare
	AliasesToExport = @()
	#Risorse DSC da esportare da questo modulo
	#DscResourcesToExport = @()
	#Elenco di tutti i moduli inclusi con questo modulo
	#ModuleList = @()
	#Elenco di tutti i file inclusi con questo modulo
	#FileList = @()
	#Dati privati da passare al modulo specificato in RootModule/ModuleToProcess. Questo può contenere anche un hashtable PSData con metadati aggiuntivi del modulo utilizzati da PowerShell
	PrivateData = @{
		PSData = @{
			#Tag applicati a questo modulo. Questi aiutano con la scoperta del modulo nelle gallerie online
			#Tags = @()
			#URL per la licenza di questo modulo
			#LicenseUri = ''
			#URL per il sito web principale di questo progetto
			#ProjectUri = ''
			#URL per un'icona che rappresenta questo modulo
			#IconUri = ''
			#Note di rilascio di questo modulo
			#ReleaseNotes = ''
		} 
		#Fine dell'hashtable PSData
	} 
	#Fine dell'hashtable PrivateData
	#URI di HelpInfo di questo modulo
	#HelpInfoURI = ''
	#Prefisso predefinito per i comandi esportati da questo modulo. Sovrascrivi il prefisso predefinito utilizzando Import-Module -Prefix
	#DefaultCommandPrefix = ''
}

Sebbene possa sembrare intimidatorio all’inizio, Microsoft ha un utile cmdlet che puoi utilizzare per generare un manifesto del modulo. Il comando incluso è New-ModuleManifest. Per generare il manifesto mostrato sopra, potresti utilizzare:

PS51> New-ModuleManifest -Path .\Scripts\TestModule.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule 'TestModule.psm1' -FunctionsToExport @('Get-RegistryKey','Set-RegistryKey') -Description 'This is a test module.'

File di aiuto esterni

Potresti anche vedere file di aiuto esterni in alcuni moduli. Possono essere identificati dal <NomeModulo>-Help.xml alla fine del nome del file. Questi file di aiuto esterni contengono le stesse informazioni che normalmente si trovano nell’aiuto basato sul comando che si può trovare in una definizione di funzione.

Questo richiederebbe anche di aggiungere # .ExternalHelp <PercorsoModulo>-Help.xml alla tua funzione per farla funzionare correttamente quando si utilizza il comando Get-Help dopo l’importazione del modulo. Di solito si vedono solo file di aiuto esterni con moduli molto grandi e per questo motivo escono dallo scopo.

Anche se questi sono i tipi di file più comuni che si trovano in un modulo, non sono gli unici file. A volte si possono trovare file binari oltre a un modulo di testo, in quanto ci sono altre dipendenze. Esplorando i percorsi dei moduli, si possono trovare molti esempi di tipi di file aggiuntivi nei moduli.

Per pubblicare correttamente file di modulo non standard, dovresti includere altri file nel parametro FileList del tuo manifesto del modulo.

All’interno del manifesto del modulo, noterai molti altri parametri attualmente vuoti. Puoi utilizzarli per definire altri requisiti per l’utilizzo del tuo modulo. Ad esempio, puoi definire le versioni di PowerShell con cui il modulo può funzionare. Se provi ad importare il modulo in una versione non supportata di PowerShell, vedrai quanto segue:

Requiring certain versions of PowerShell

PSRepositories

Una delle opzioni chiave di distribuzione per i moduli è un PSRepository. A grandi linee, un PSRepository è un luogo locale in cui più persone o più dispositivi possono accedere ai file del modulo. Questi sono spesso server web in cui è possibile pubblicare file.

Puoi anche utilizzare una directory per il repository, ma ciò limita le funzionalità del tuo repository. Puoi ospitare tu stesso un PSRepository, oppure puoi utilizzare una delle molte opzioni disponibili su Internet come PowerShell Gallery. Puoi visualizzare i tuoi PSRepositories utilizzando il comando Get-PSRepository.

Default PowerShell NuGet repositories

Per impostazione predefinita, avrai solo un’entrata, che sarà per PowerShell Gallery. Potresti notare che verrà indicato come non attendibile. Questo perché PowerShell ti informa che utilizzando PowerShell Gallery potresti utilizzare codice non scritto e approvato da Microsoft. Ciò significa che prima che vengano installati moduli da essa, dovrai dare esplicito permesso.

Aggiunta di PSRepositories

Puoi anche aggiungere i tuoi repository. Per fidarti di PowerShell Gallery, puoi eseguire il comando Get-PSRepository -Name PSGallery | Set-PSRepository -InstallationPolicy Trusted oppure puoi accettare l’avviso la prima volta che installi un modulo da PowerShell Gallery.

Tutti i comandi che utilizzeresti per interagire con questi PSRepositories possono essere trovati nel modulo PowerShellGet. Puoi vedere le funzioni qui:

Commands in the PowerShellGet module

Potrebbe essere necessario aggiornare il modulo PowerShellGet prima di interagire con determinati repository.

Trovare moduli

Un’altra caratteristica chiave nell’utilizzo di un PSRepository è la possibilità di cercare moduli. Questo viene fatto utilizzando il comando Find-Module. Ci sono molti modi per filtrare e trovare esattamente ciò che stai cercando, ma per ora puoi cercare i moduli VMware in questo modo:

Finding modules on the PowerShell Gallery

Questo mostrerà tutti i moduli che iniziano con VMware. Anche se la maggior parte di questi è di VMware, è necessario guardare l’attributo dell’autore per vedere chi ha pubblicato il modulo.

Dal momento che chiunque può caricare su PowerShell Gallery, ci sono migliaia di moduli disponibili. Ciò significa che potresti trovare moduli che non funzionano correttamente per il tuo caso d’uso. Molti moduli che troverai sono open source, quindi puoi contribuire per migliorare la funzionalità del modulo.

Installazione dei moduli

Per utilizzare il comando Install-Module, devi avere un PSRepository affidabile che ospita il modulo. Questo può essere PowerShell Gallery, un altro PSRepository su Internet o un sito autogestito. Puoi utilizzare il piping dal comando Find-Module per confermare facilmente il modulo prima di installarlo.

Finding modules installed from a PSRepository

Puoi anche definire la versione di un modulo utilizzando i parametri MinimumVersion, MaximumVersion o RequiredVersion.

Per visualizzare tutti i moduli installati utilizzando il comando Install-Module, puoi utilizzare il comando Get-InstalledModule. Questo elencherà tutti i moduli installati nello scope AllUsers o nel tuo scope CurrentUser.

Disinstallazione dei moduli

Come per l’installazione di un modulo, è possibile anche disinstallare un modulo. Se il modulo non è stato installato tramite il comando Install-Module, non è possibile disinstallarlo con il comando Uninstall-Module.

Uninstalling modules installed from a PSRepository with Uninstall-Module

Come puoi vedere qui, stiamo cercando di disinstallare il modulo ActiveDirectory. Poiché questo modulo non è stato installato con Install-Module, riceverai un errore quando cercherai di utilizzare Uninstall-Module. Per disinstallare questo modulo, dovremmo disinstallarlo invertendo ciò che hai usato per installare il modulo.

Per vedere una disinstallazione di successo di un modulo, puoi disinstallare il modulo VMware.PowerCLI che hai installato in precedenza.

Uninstalling a module downloaded from the PowerShell Gallery

Anche se hai disinstallato VMware.PowerCLI, puoi vedere che sono ancora installate molte dipendenze. Se volessi disinstallare tutti i moduli, potremmo utilizzare il comando Get-InstalledModule VMware.* | Uninstall-Module -Force.

Il motivo per cui avresti difficoltà a disinstallare completamente questo modulo è perché ha molte dipendenze. Inoltre, alcuni di questi moduli sono dipendenze l’uno dell’altro, motivo per cui è necessario utilizzare il parametro Force.

Aggiornamento dei moduli

Ora che sai come installare e disinstallare un modulo, potresti chiederti come aggiornare un modulo che hai installato.

Come per gli altri processi, se il modulo non è stato installato utilizzando Install-Module, non puoi aggiornarlo utilizzando i comandi di PowerShell. Puoi utilizzare Update-Module per aggiornare un modulo all’ultima versione o a una versione specifica più recente.

C’è anche uno switch AllowPreRelease che ti permette di aggiornare a una versione non ufficialmente rilasciata. A volte questo può essere utile se è stato corretto un bug che stai riscontrando o se è stata aggiunta una nuova funzionalità che desideri utilizzare.

Updating modules with Update-Module

Ispezione/Salvataggio di un modulo

Uno dei comandi meno utilizzati ma molto utili per verificare i moduli prima dell’uso è Save-Module. Utilizzando questo comando, puoi scaricare un modulo in una determinata posizione senza installarlo.

Puoi quindi ispezionare i file e se il modulo non è un modulo binario, puoi aprirlo e visualizzare il codice che lo compone. Questo può essere utile non solo per assicurarti che un modulo non stia facendo nulla di malevolo, ma anche per imparare come gli altri strutturano i loro moduli.

Downloading modules with Save-Module

In questo esempio, viene scaricato non solo il modulo VMware.PowerCLI, ma anche tutte le dipendenze. Ecco cosa viene mostrato nella cartella VMware.PowerCLI:

VMware.PowerCLI module contents

Questo è un buon esempio che mostra come talvolta sono inclusi nel modulo file non standard come l’accordo di licenza per l’utente finale.

Scrivere il proprio modulo

Ora hai visto come interagire con il modulo di qualcun altro. Ora vuoi imparare come crearne uno proprio in modo da poter ottimizzare il tuo codice per la scalabilità.

Crea file di modello

Prima devi creare una cartella per tutti i file del tuo modulo. Dopo aver creato il contenitore, devi creare il file del modulo. Devi assicurarti che il file del modulo abbia lo stesso nome della tua cartella, altrimenti quando cerchi di pubblicare il tuo modulo, PowerShell non troverà correttamente il modulo.

PS51> New-Item -Path .\Scripts -Name ATARegistry -ItemType Directory
PS51> New-Item -Path .\Scripts\ATARegistry -Name ATARegistry.psm1

Ora vuoi anche usare un manifesto, dovrai anche dargli lo stesso nome del contenitore e del file del modulo.

PS51> New-ModuleManifest -Path .\Scripts\ATARegistry\ATARegistry.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule ATARegistry.psm1 -Description 'Used for interacting with registry keys'

Con il contenitore, il file del modulo e il file del manifesto, hai un modulo completamente funzionante. Potresti pubblicare questo modulo su un PSRepository e iniziare a installarlo ovunque tu voglia. Anche se il file del modulo è vuoto, probabilmente non ti servirà molto. Puoi comunque usare questi file per testare la pubblicazione e verificare che il tuo repository funzioni.

Registrazione di un PSRepository

Prima di poter pubblicare il tuo modulo, dovrai aggiungere un altro PSRepository alla tua sessione. Per i test, puoi utilizzare un percorso locale come tuo PSRepository poiché sarà facile da configurare e disinstallare.

Normalmente, se stavi configurando un PSRepository con una directory, vorresti assicurarti che più computer possano accedervi. Puoi creare un repository locale in questo modo:

PS51> New-Item -Path C:\ -Name Repo -ItemType Directory
PS51> Register-PSRepository -Name 'LocalRepo' -SourceLocation 'C:\Repo' -PublishLocation 'C:\Repo' -InstallationPolicy Trusted

Se stessi solo scaricando dal PSRepository e non pubblicando, potresti escludere il parametro PublishLocation.

Pubblicazione del tuo modulo

Poiché hai già impostato la policy di installazione come attendibile, non riceverai una conferma per consentire l’installazione di un modulo dal repository. Ora che hai un nuovo PSRepository disponibile, puoi pubblicare il tuo modulo utilizzando Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo.

Dopo aver pubblicato il tuo modulo, puoi utilizzare i comandi precedenti per trovare il modulo e installarlo.

Ora che hai installato il modulo, puoi utilizzare Get-Module per vedere il modulo importato nella tua sessione locale. Poiché non hai aggiunto alcuna funzione all’array FunctionsToExport nel manifesto, la proprietà ExportedCommands è vuota.

No exported commands

Aggiunta al tuo modulo

Ora che sai di poter pubblicare e installare il tuo modulo, puoi iniziare ad aggiungere alcune funzionalità. Potresti aggiungere una funzione per restituire una chiave di registro in questo modo:

function Get-ATARegistryKey {
    param (
        [string]$Path
    )
    Get-Item $Path
}

Se lasciassi il manifesto com’è e cercassi di caricare il tuo nuovo modulo, incontreresti due problemi. Il primo è che riceveresti un errore che indica che la versione del tuo modulo esiste già nel repository. Questo perché non hai modificato la versione del modulo nel file del manifesto.

Esportazione delle funzioni del modulo

L’altro problema sarebbe che dopo aver importato il modulo, non vedresti ancora alcuna funzione nella proprietà ExportedCommands perché non hai aggiunto la tua nuova funzione al manifesto.

Anche se la tua funzione potrebbe essere utilizzata senza essere elencata nell’elenco FunctionsToExport, sarebbe molto più difficile trovarla.

Finché non definisci un array vuoto, @(), per la tua variabile FunctionsToExport, tutte le funzioni, variabili e alias vengono esportati per impostazione predefinita.

Per risolvere questi due problemi, puoi aggiornare il file del modulo in questo modo:

ModuleVersion = '1.1'
FunctionsToExport = 'Get-RegistryKey'

Ora che hai aggiunto una funzione al tuo modulo e hai aggiornato il manifesto per riflettere queste modifiche, puoi pubblicare la nuova versione del modulo utilizzando lo stesso comando di prima.

PS51> Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo.

Scegliere tra FunctionsToExport ed Export-ModuleMember

Esistono due funzionalità simili di PowerShell per l’esportazione dei membri del modulo. La sfida consiste nel decidere tra le due. Entrambe sono corrette, ma una potrebbe funzionare meglio per te, a seconda delle tue esigenze.

Quando desideri controllare dinamicamente quali funzioni vengono esportate, utilizza Export-ModuleMember in quanto puoi passare un elenco di funzioni da esportare. Di solito, ciò viene utilizzato quando si includono più file PS1 di funzione tramite dot-sourcing. Suddividendo le funzioni interne in una cartella privata e le funzioni esportabili in una cartella pubblica, puoi facilmente esportare solo le funzioni pubbliche passando tutte le funzioni pubbliche alla funzione Export-ModuleMember.

A few notes about Export-ModuleMember:

  • Sovrascrive il comportamento di FunctionsToExport, quindi se viene utilizzato un comando Export-ModuleMember, FunctionsToExport non ha effetto.
  • Export-ModuleMember non esporta variabili e alias a meno che non vengano definiti esplicitamente, a differenza di FunctionsToExport, che li esporta.
  • Puoi utilizzare più comandi Export-ModuleMember e si accumulano invece di avere la precedenza.

Se non prevedi di apportare modifiche all’elenco delle funzioni, l’utilizzo della configurazione FunctionsToExport nel manifesto del modulo funziona bene e non richiede di esportare esplicitamente variabili e alias.

Aggiornamento del modulo

L’ultimo passaggio consiste nell’aggiornare il modulo nella sessione per poter utilizzare i file aggiornati. Utilizzando Update-Module ATARegistry scarichi l’aggiornamento appena pubblicato nel repository.

Exported commands now show up

Ora puoi vedere che hai la nuova versione del modulo e puoi visualizzare la funzione che hai definito nel manifesto.

Creazione del contenuto della guida

Una delle opzioni che è stata tralasciata in precedenza è il sistema di aiuto integrato in PowerShell. Probabilmente hai utilizzato Get-Help su una funzione. Queste informazioni possono essere aggiunte in due modi principali.

Il primo consiste nell’aggiungere un aiuto basato su commenti nella definizione della funzione. Questo è di solito il modo in cui molti autori di moduli implementano. L’altro modo è utilizzare un file di aiuto esterno. Puoi utilizzare il parametro Full per visualizzare tutto ciò che l’aiuto ha da offrire.

Finding help with Get-Help

Come puoi vedere, in realtà non c’è molta informazione e la piccola informazione che ottieni probabilmente non sarebbe utile a nessuno.

Puoi aggiungere un aiuto basato su commenti al tuo file di modulo per popolare questi campi nel sistema di aiuto. Puoi leggere tutte le opzioni per l’aiuto basato su commenti utilizzando Get-Help about_Comment_Based_Help.

Per ora, puoi aggiornare la tua funzione in questo modo. Questa è una lista dei parametri di aiuto più comunemente utilizzati, ma tutti questi sono ancora opzionali e ne potrebbero essere aggiunti altri al loro posto.

Ora la tua funzione appare così:

 function Get-RegistryKey {
	<#
	    .SYNOPSIS
	    Restituisce la chiave di registro utilizzando il percorso fornito.
	    .DESCRIPTION
	    La funzione utilizza il comando Get-Item per restituire le informazioni relative a una chiave di registro fornita.
	    .PARAMETER Path
	    Il percorso in cui verrà cercata una chiave di registro.
	    .EXAMPLE
	    Get-RegistryKey -Path 'HKLM:\HARDWARE\DESCRIPTION\System'
	    .INPUTS
	    System.String
	    .OUTPUTS
	    Microsoft.Win32.RegistryKey
	    .NOTES
	    Questo modulo è un esempio di come potrebbe apparire una funzione ben documentata.
	    .LINK
	
ATA Learning
#>
param( [string]$Path ) Get-Item $Path }

Ci sono alcuni parametri di aiuto speciali, come .FORWARDHELPTARGETNAME. Questa opzione inoltra tutte le richieste di aiuto in arrivo a un comando diverso. Questo potrebbe essere utilizzato nel caso in cui l’aiuto debba mostrare le stesse informazioni per più comandi.

Ora che hai aggiunto l’aiuto, puoi aggiornare la versione nel manifesto del modulo, pubblicare la nuova versione e aggiornare la versione installata per la tua sessione come hai fatto prima.

Se ora guardi l’aiuto per la funzione, puoi vedere che sono disponibili molte più informazioni. Questo è un ottimo modo per includere la documentazione su come utilizzare le funzioni, specialmente per qualcuno che ha meno esperienza e potrebbe non essere in grado di capire rapidamente cosa fa il modulo guardando il codice.

Getting full help content with Get-Help

Nel caso di un file di aiuto esterno, le informazioni aggiunte sono le stesse, ma vengono inserite in un file separato e collegato all’interno della funzione.

Se guardi nel percorso del modulo AllUsers, puoi vedere la versione del modulo e tutti i file del modulo che hai installato.

Folder name is the module version

Se torni al percorso del tuo PSRepository C:\Repo che hai creato in precedenza, puoi vedere un gruppo di file NUPKG. Ce ne sarà uno per ogni versione pubblicata. Queste sono versioni compressi di ciò che hai pubblicato quando usi Publish-Module.

Sommario

Una volta che hai padroneggiato la console di PowerShell, PowerShell come linguaggio e la scrittura di script, la creazione dei tuoi moduli è l’ultimo passo. I moduli ti consentono di iniziare a sviluppare strumenti utili in PowerShell. Se progettati e costruiti correttamente, creando moduli per uno scopo specifico, ti troverai inevitabilmente a scrivere sempre meno codice nel tempo. Inizierai a riferirti alle funzioni del tuo modulo in più codice e a costruire da lì.

Le funzioni del modulo ti permettono di astrarre il codice che ti ritrovi a ripetere negli script. Rappresentano “etichette” da richiamare in seguito nel codice che possono essere chiamate in qualsiasi momento anziché reinventare la ruota e cercare di capire come hai già raggiunto il tuo obiettivo in precedenza. I moduli rappresentano l’ultimo “pacchetto” del codice PowerShell che raggruppa codice simile per evitare di perdere tempo su problemi che hai già risolto.

Source:
https://adamtheautomator.com/powershell-modules/