Tutti i comandi PowerShell possono avere uno o più parametri, a volte chiamati argomenti. Se non stai utilizzando i parametri PowerShell nelle tue funzioni PowerShell, non stai scrivendo un buon codice PowerShell!
In questo articolo, imparerai praticamente ogni aspetto della creazione e dell’uso dei parametri o degli argomenti di PowerShell!
Questo è un esempio tratto dal mio libro PowerShell for SysAdmins. Se vuoi imparare PowerShell o imparare alcuni trucchi del mestiere, dagli un’occhiata!
Perché hai bisogno di un parametro?
Quando inizi a creare funzioni, avrai l’opzione di includere parametri o meno e come funzionano quei parametri.
Supponiamo tu abbia una funzione che installa Microsoft Office. Forse chiama l’installatore di Office in modo silenzioso all’interno della funzione. Ciò che fa la funzione non importa per i nostri scopi. La funzione di base ha questo aspetto con il nome della funzione e il blocco di script.
In questo esempio, hai appena eseguito Install-Office
senza parametri e fa ciò che deve fare.
Non importava se la funzione Install-Office
aveva parametri o meno. Apparentemente non aveva parametri obbligatori; altrimenti, PowerShell non ci avrebbe permesso di eseguirlo senza utilizzare un parametro.
Quando usare un parametro PowerShell
Office ha molte versioni diverse. Forse è necessario installare Office 2013 e 2016. Attualmente, non hai modo di specificare questo. Potresti cambiare il codice della funzione ogni volta che desideri modificare il comportamento.
Ad esempio, potresti creare due funzioni separate per installare versioni diverse.
Fare questo funziona, ma non è scalabile. Ti costringe a creare una funzione separata per ogni singola versione di Office che esce. Sarai costretto a duplicare molto codice quando non è necessario.
Invece, hai bisogno di un modo per passare valori diversi al momento dell’esecuzione per modificare il comportamento della funzione. Come si fa questo?
Sì! Parametri o quello che alcuni chiamano argomenti.
Dato che vorremmo installare diverse versioni di Office senza cambiare il codice ogni volta, devi aggiungere almeno un parametro a questa funzione.
Prima di pensare rapidamente a un parametro di PowerShell da usare, è essenziale chiedersi prima di tutto una domanda; “Qual è il cambiamento o i cambiamenti più piccoli che ti aspetti saranno necessari in questa funzione?”.
Ricorda che devi rieseguire questa funzione senza cambiare alcun codice all’interno della funzione stessa. In questo esempio, il parametro probabilmente ti è chiaro; devi aggiungere un parametro Versione
. Ma, quando hai una funzione con decine di righe di codice, la risposta non sarà troppo evidente. Finché rispondi a quella domanda nel modo più preciso possibile, ti aiuterà sempre.
Quindi sai di aver bisogno di un parametro Versione
. Ora cosa? Ora puoi aggiungerne uno, ma come qualsiasi grande linguaggio di programmazione, ci sono più modi per farlo.
In questo tutorial, ti mostrerò il modo “migliore” per creare parametri basato sulla mia esperienza di quasi un decennio con PowerShell. Tuttavia, sappi che questo non è l’unico modo per creare un parametro.
Esiste una cosa chiamata parametri posizionali. Questi parametri ti permettono di passare valori ai parametri senza specificare il nome del parametro. I parametri posizionali funzionano ma non sono considerati “la pratica migliore”. Perché? Perché sono più difficili da leggere, specialmente quando hai molti parametri definiti su una funzione.
Creare un Semplice Parametro PowerShell
Creare un parametro su una funzione richiede due componenti principali; un blocco param e il parametro stesso. Un blocco param è definito dalla parola chiave param
seguita da un set di parentesi.
A questo punto, la funzionalità effettiva della funzione non è cambiata affatto. Abbiamo solo messo insieme un po’ di tubature, preparandoci per il primo parametro.
Una volta che abbiamo il blocco param in posizione, ora creerai il parametro. Il metodo che sto suggerendo per creare un parametro include il blocco Parameter
, seguito dal tipo di parametro, seguito dal nome della variabile parametro qui sotto.
Abbiamo ora creato un parametro di funzione in PowerShell ma cosa è esattamente successo qui?
Il blocco Parameter
è un pezzo opzionale ma consigliato di ogni parametro. Come il blocco param, è una “tubatura di funzione”, che prepara il parametro per l’aggiunta di ulteriori funzionalità. La seconda riga è dove definisci il tipo di parametro che è.
In questo caso, abbiamo scelto di convertire il parametro Version
in una stringa. Definire esplicitamente il tipo significa che qualsiasi valore passato a questo parametro verrà sempre “convertito” in una stringa se non lo è già.
Il tipo non è obbligatorio, ma è altamente consigliato. Definire esplicitamente il tipo del parametro ridurrà significativamente molte situazioni indesiderate in futuro. Fidati di me.
Ora che hai definito il parametro, puoi eseguire il comando Install-Office
con il parametro Version
passando una stringa di versione come 2013. Il valore passato al parametro Version
viene talvolta indicato come argomenti o valori del parametro.
Cosa sta succedendo qui comunque? Hai detto che volevi installare la versione 2013, ma ti sta ancora dicendo che ha installato la versione 2016. Quando aggiungi un parametro, devi poi ricordarti di cambiare il codice della funzione in una variabile. Quando il parametro viene passato alla funzione, quella variabile verrà espansa per essere qualsiasi valore sia stato passato.
Cambia il testo statico di 2016 e sostituiscilo con la variabile del parametro Version
e converti i singoli apici in doppi apici in modo che la variabile si espanda.
Ora puoi vedere che qualsiasi valore passi al parametro Version
verrà poi passato nella funzione come variabile $Version
.
L’attributo del parametro obbligatorio
Ricorda che ho menzionato che la riga [Parameter ()]
era solo “plumbing della funzione” e doveva preparare la funzione per lavori successivi? Aggiungere attributi di parametro a un parametro è il lavoro aggiuntivo di cui parlavo in precedenza.
A parameter doesn’t have to be a placeholder for a variable. PowerShell has a concept called parameter attributes and parameter validation. Parameter attributes change the behavior of the parameter in a lot of different ways.
Ad esempio, uno degli attributi di parametro più comuni che imposterai è la parola chiave Mandatory
. Per impostazione predefinita, potresti chiamare la funzione Install-Office
senza utilizzare il parametro Version
e funzionerebbe correttamente. Il parametro Version sarebbe opzionale. Ammesso che non espanderebbe la variabile $Version all’interno della funzione perché non c’era alcun valore, ma comunque si eseguirebbe.
Spesso, quando si crea un parametro, si desidera che l’utente utilizzi sempre quel parametro. Ti affiderai al valore del parametro all’interno del codice della funzione da qualche parte e se il parametro non viene passato, la funzione avrà esito negativo. In questi casi, si desidera obbligare l’utente a passare questo valore di parametro alla tua funzione. Vuoi che quel parametro diventi obbligatorio.
Obbligare gli utenti a utilizzare un parametro è semplice una volta che hai costruito il framework di base come hai fatto qui. Devi includere la parola chiave Mandatory
all’interno delle parentesi del parametro. Una volta che hai fatto questo, l’esecuzione della funzione senza il parametro si interromperà fino a quando non verrà inserito un valore.
La funzione attende finché non specifici un valore per il parametro Version
. Una volta fatto ciò e premi Invio, PowerShell eseguirà la funzione e passerà oltre. Se fornisci un valore per il parametro, PowerShell non ti richiederà il parametro ogni volta.
Attributi di Validazione dei Parametri di PowerShell
Rendere un parametro obbligatorio è uno degli attributi di parametro più comuni che è possibile aggiungere, ma è anche possibile utilizzare attributi di validazione del parametro. In programmazione, è sempre essenziale limitare l’input dell’utente il più possibile. Limitare le informazioni che gli utenti (o anche tu!) possono passare alle tue funzioni o script eliminerà codice superfluo all’interno della tua funzione che deve tener conto di tutte le situazioni.
Apprendimento tramite Esempio
Ad esempio, nella funzione Install-Office
, ho dimostrato di passare il valore 2013
perché sapevo che avrebbe funzionato. Ho scritto il codice! Sto supponendo (mai farlo nel codice!) che sia ovvio che chiunque sappia qualcosa specifica la versione come 2013 o 2016. Beh, ciò che è ovvio per te potrebbe non esserlo altrettanto per altre persone.
Se vuoi diventare tecnico sulle versioni, sarebbe probabilmente più preciso specificare la versione 2013 come 15.0
e 2016 come 16.0
se Microsoft utilizzasse ancora lo schema di versionamento che ha utilizzato in passato. Ma cosa succede se, poiché stai assumendo che specificano una versione del 2013 o 2016, hai del codice all’interno della funzione che cerca cartelle con quelle versioni o qualcos’altro?
Ecco un esempio di dove potresti utilizzare la stringa $Version
in un percorso del file. Se qualcuno passa un valore che non completa un nome cartella come Office2013
o Office2016
, fallirà o farà qualcosa di peggio, come rimuovere cartelle non previste o cambiare cose che non hai considerato.
Per limitare l’utente a ciò che si aspetta di inserire, è possibile aggiungere una validazione del parametro PowerShell.
Utilizzo dell’attributo di validazione del parametro ValidateSet
Esistono vari tipi di validazione del parametro che è possibile utilizzare. Per un elenco completo, eseguire Get-Help about_Functions_Advanced_Parameters
. In questo esempio, l’attributo ValidateSet
sarebbe probabilmente il migliore.
L’attributo di validazione ValidateSet
consente di specificare un elenco di valori consentiti come valore del parametro. Poiché stiamo considerando solo la stringa 2013 o 2016, desidero assicurarmi che l’utente possa specificare solo questi valori. In caso contrario, la funzione fallirà immediatamente, avvisandolo del motivo.
È possibile aggiungere attributi di validazione del parametro subito sotto la parola chiave Parameter
originale. In questo esempio, all’interno delle parentesi dell’attributo del parametro, si ha un array di elementi; 2013 e 2016. Un attributo di validazione del parametro indica a PowerShell che i soli valori validi per Version
sono 2013 o 2016. Se si prova a passare qualcosa diverso da quello presente nell’insieme, verrà visualizzato un errore che indica che sono disponibili solo un numero specifico di opzioni.
L’attributo ValidateSet
è un attributo di convalida comune da utilizzare. Per una panoramica completa di tutti i modi in cui i valori dei parametri possono essere limitati, consulta l’argomento di aiuto Functions_Advanced_Parameters
eseguendo Get-Help about_Functions_Advanced_Parameters
.
Set di parametri
Supponiamo che tu voglia solo che certi parametri di PowerShell siano utilizzati con altri parametri. Forse hai aggiunto un parametro Path
alla funzione Install-Office
. Questo percorso installerà qualsiasi versione sia disponibile. In questo caso, non vuoi che l’utente utilizzi il parametro Version
.
Hai bisogno di set di parametri.
I parametri possono essere raggruppati in set che possono essere utilizzati solo con altri parametri nello stesso set. Utilizzando la funzione di seguito, ora puoi utilizzare sia il parametro Version
che il parametro Path
per generare il percorso per l’installatore.
Questo pone però un problema, perché l’utente potrebbe utilizzare entrambi i parametri. Inoltre, poiché entrambi i parametri sono obbligatori, saranno costretti a utilizzarli entrambi quando non è quello che desideri. Per risolvere questo problema, possiamo inserire ciascun parametro in un set di parametri come segue.
Definendo un nome per il set di parametri su ciascun parametro, ciò ti consente di controllare gruppi di parametri insieme.
Set di parametri predefinito
Cosa succede se l’utente cerca di eseguire Install-Office
senza parametri? Questo non è previsto e verrà visualizzato un messaggio di errore amichevole.

Per risolvere questo, dovrai definire un insieme di parametri predefinito all’interno dell’area CmdletBinding()
. Questo dice alla funzione di scegliere un insieme di parametri da utilizzare se non vengono utilizzati parametri espliciti, modificando [CmdletBinding()]
in [CmdletBinding(DefaultParameterSetName = 'ByVersion')]
Ora, ogni volta che esegui Install-Office
, chiederà il parametro Version
poiché userà quel set di parametri.
Input del Pipeline
Nei precedenti esempi, hai creato funzioni con un parametro di PowerShell che può essere passato solo utilizzando la sintassi tipica -NomeParametro Valore. Ma, come hai già appreso, PowerShell ha un pipeline intuitiva che ti consente di passare senza soluzione di continuità oggetti da un comando a un altro senza utilizzare la sintassi “tipica”.
Quando usi il pipeline, “concateni” i comandi con il simbolo pipe |
consentendo all’utente di inviare l’output di un comando come Get-Service
a Start-Service
come scorciatoia per passare il parametro Nome
a Start-Service
.
Il “Vecchio” Metodo Utilizzando un Ciclo
Nella funzione personalizzata con cui stai lavorando, stai installando Office e hai un parametro Versione
. Diciamo che hai una lista di nomi di computer in un file CSV in una riga con la versione di Office che deve essere installata su di essi nella seconda riga. Il file CSV assomiglia a qualcosa del genere:
Vorresti installare la versione di Office che è accanto a ciascun computer su quel computer.
Innanzitutto, dovrai aggiungere un parametro ComputerName
alla funzione per passare un nome computer diverso per ogni iterazione della funzione. Di seguito ho creato del pseudocodice che rappresenta parte del codice che potrebbe essere presente nella funzione fittizia e ho aggiunto un’istanza Write-Host
per vedere come le variabili si espandono all’interno della funzione.
Una volta che hai aggiunto il parametro ComputerName
alla funzione; potresti far succedere ciò leggendo il file CSV e passando i valori del nome del computer e della versione alla funzione Install-Office
.
Creazione di Input per la Pipeline dei Parametri
Questo metodo di lettura delle righe del CSV e utilizzo di un loop per passare le proprietà di ogni riga alla funzione è il “vecchio” modo di farlo. In questa sezione, vuoi evitare completamente il ciclo foreach
e utilizzare invece la pipeline.
Come è, la funzione non supporta affatto la pipeline. Avrebbe senso intuitivo presumere che potresti passare ogni nome computer e versione alla funzione utilizzando la pipeline. Di seguito, stiamo leggendo il CSV e passandolo direttamente a Install-Office,
ma ciò non funziona.
Puoi supporre tutto ciò che vuoi, ma questo non lo fa funzionare automaticamente. Ci viene richiesto il parametro Version
quando sai che Import-Csv
lo sta inviando come proprietà dell’oggetto. Perché non funziona? Perché non hai ancora aggiunto il supporto per il pipeline.
Esistono due tipi di input da pipeline in una funzione di PowerShell; ByValue (intero oggetto) e ByPropertyName (una singola proprietà dell’oggetto). Quale pensi sia il modo migliore per collegare l’output di Import-Csv
all’input di Install-Office
?
Senza alcun refactoring, potresti utilizzare il metodo ByPropertyName
poiché, dopo tutto, Import-Csv
sta già restituendo le proprietà Version
e ComputerName
poiché sono colonne nel CSV.
Aggiungere il supporto per il pipeline a una funzione personalizzata è molto più semplice di quanto possa sembrare. È semplicemente un attributo del parametro rappresentato con una delle due parole chiave; ValueFromPipeline
o ValueFromPipelineByPropertyName
.
Nell’esempio, desideri vincolare le proprietà ComputerName
e Version
restituite da Import-Csv
ai parametri Version
e ComputerName
di Install-Office
quindi utilizzerai ValueFromPipelineByPropertyName
.
Dato che desideriamo vincolare entrambi questi parametri, aggiungerai questa parola chiave a entrambi i parametri come mostrato di seguito e rieseguirai la funzione utilizzando il pipeline.
È strano. È stato eseguito solo per l’ultima riga nel CSV. Cosa sta succedendo? Ha eseguito solo la funzione per l’ultima riga perché hai saltato un concetto che non è richiesto quando si costruiscono funzioni senza supporto per il pipeline.
Non dimenticare il blocco di processo!
Quando devi creare una funzione che coinvolge il supporto per il pipeline, devi includere (almeno) un blocco “integrato” all’interno della tua funzione chiamata. process
. Questo blocco di processo dice a PowerShell che quando riceve input dal pipeline, esegua la funzione per ogni iterazione. Per impostazione predefinita, eseguirà solo l’ultima.
Potresti tecnicamente aggiungere altri blocchi come begin
e end
anche, ma gli scripter non li usano così spesso.
Per dire a PowerShell di eseguire questa funzione per ogni oggetto in ingresso, aggiungerò un blocco process
che include il codice all’interno di quello.
Ora puoi vedere che le proprietà Version
e ComputerName
di ogni oggetto restituito da Import-Csv
sono state passate a Install-Office
e vincolate ai parametri Version
e ComputerName
.
Risorse
Per approfondire il funzionamento dei parametri delle funzioni, dai un’occhiata al mio post sul blog sulle funzioni di PowerShell.
I also encourage you to check my Pluralsight course entitled Building Advanced PowerShell Functions and Modules for an in-depth breakdown of everything there is to know about PowerShell functions, function parameters, and PowerShell modules.