Funzioni PowerShell
In questo episodio della serie Learn PowerShell esamineremo le funzioni PowerShell. Nell’ultimo episodio abbiamo coperto gli script PowerShell dove abbiamo iniziato a creare soluzioni e risolvere problemi usando PowerShell. Gli script PowerShell sono fantastici e molte persone passano un bel po’ di tempo in questa fase dell’apprendimento di PowerShell. Gli script ti permettono di mantenere le cose abbastanza semplici e possono aiutarti ad automatizzare rapidamente i compiti. Man mano che migliori e cominci a scrivere più PowerShell avrai bisogno di guardare alla creazione di funzioni PowerShell!
Video
Se preferisci il formato video alla documentazione scritta, discuto questo argomento nel seguente video TechThoughts:
Quando dovresti scrivere una funzione PowerShell
In fin dei conti uno script PowerShell è un insieme di codice che esegue un compito. Questo è ciò che fa anche una funzione PowerShell! Quindi, perché dovresti scegliere di scrivere una funzione piuttosto che uno script? Ci immergeremo in alcune ragioni qui sotto. In generale, però, uno script è qualcosa per te. Quando volete iniziare a condividere il vostro codice, o a farlo utilizzare ai vostri compagni di squadra, vorrete iniziare ad utilizzare alcune delle capacità che le funzioni forniscono. Non c’è una linea fissa. Per un compito veloce che sarà eseguito sulla vostra stazione di lavoro una sola volta, uno script potrebbe avere senso. Se stai scrivendo qualche PowerShell che altri potrebbero usare, o che potresti usare più di una volta, una funzione probabilmente servirà meglio.
- Singolo scopo – una funzione è tipicamente usata per eseguire un compito ristretto e “fare una cosa, e farla bene”. Questo rende le funzioni altamente riutilizzabili. Se scrivi una funzione di logging per esempio, puoi poi usare quella funzione di logging di PowerShell con altre funzioni o script.
- Aiuto – le funzioni supportano commenti basati sull’aiuto. Questo permette ai tuoi utenti di fare cose come digitare Get-Help e capire come usare la tua funzione.
- Parametri – il supporto per le dichiarazioni e il controllo dei parametri semplici e avanzati permette alla tua funzione di essere dinamica e prendere varie forme di input dell’utente.
- Testabile – le funzioni possono essere testate e derise, il che migliora notevolmente la qualità del codice.
Anatomia di una funzione PowerShell
Qui è il layout di base e l’ordine di una funzione PowerShell. Ci immergeremo in ciascuna di queste sezioni di seguito e le esploreremo in dettaglio.
# function help - (optional but strongly encouraged)# function name# CmdletBinding - (optional)# parameters - (optional)# function logic (optional Begin / Process / End)# return - (optional)function Verb-Noun { param ( ) begin { } process { } end { }}
Aiuto della funzione
Quando includi un aiuto all’inizio della tua funzione, questo verrà visualizzato quando Get-Help viene eseguito contro la tua funzione. Questa è una capacità potente quando gli altri stanno esplorando il vostro codice. Prendersi il tempo di riempire una buona sinossi e descrizione combinate con solidi esempi aiuterà gli altri a capire a cosa serve la tua funzione e come usarla.
Tutti i campi di aiuto sono opzionali e puoi aggiungerli o rimuoverli a tuo piacimento. Ti consiglio di includere almeno i campi sottostanti.
<#.SYNOPSIS Short description.DESCRIPTION Long description.EXAMPLE C:\PS> Example of how to use this cmdlet.EXAMPLE C:\PS> Another example of how to use this cmdlet.PARAMETER InputObject Specifies the object to be processed. You can also pipe the objects to this command..OUTPUTS Output from this cmdlet (if any).NOTES General notes.COMPONENT The component this cmdlet belongs to#>
CmdletBinding
Quando scrivi una grande funzione e le dai un nome come Get-AllFileInformation, sembra e si comporta come una cmdlet. Ma è una distinzione importante che una funzione PowerShell non è una cmdlet. I cmdlet sono scritti e compilati in C# e la tua funzione PowerShell è scritta in PowerShell.
CmdletBinding è un attributo delle funzioni che abilita capacità che le fanno operare più come cmdlet compilati. Aggiungendolo all’inizio della vostra funzione, questa darà alla vostra funzione un sacco di capacità aggiuntive come:
- Write-Verbose – permette agli utenti di usare lo switch -Verbose per vedere cosa sta facendo la vostra funzione mentre lo sta facendo.
- ShouldProcess – se la vostra funzione farà un cambiamento ad un sistema che è ad alto rischio, potreste volere che l’utente confermi l’azione.
- PositionalBinding – permette alla vostra funzione di essere eseguita senza fornire esplicitamente il nome di ogni parametro. I valori possono essere dedotti dall’ordine in cui vengono forniti alla tua funzione
parametri
param ( $City, $Units = 'USCS', $Language = 'en', $Short)
I parametri servono a fornire all’utente un modo di interagire dinamicamente con la tua funzione. Potete accettare varie forme di input ed eseguire un’ampia varietà di controlli e convalide per assicurarvi di ottenere il giusto tipo di informazioni.
Potete rimanere molto semplici e dichiarare solo i nomi dei vostri parametri. In alternativa, potete essere molto specifici su ciò che è richiesto per i vostri parametri:
- Se il parametro è obbligatorio
- La posizione di un parametro (l’ordine)
- Il tipo di parametro (stringa/int/bool/ecc)
- Impostazione dei valori di default
- Convalida degli input
- Insiemi di parametri
- Molto di più
Questo post non può coprire ogni possibile configurazione dei parametri. Anche dopo anni di scrittura di PowerShell trovo difficile memorizzare tutte le impostazioni dei parametri e la sintassi. Sappiate che le dichiarazioni dei parametri sono il vostro modo di prendere input nella vostra funzione. Puoi fornire molti dettagli e controlli ad essi, o semplicemente mantenerli semplici a seconda delle tue esigenze. Segnatevi i link dei parametri in fondo a questo post. Ancora oggi, li visito frequentemente!
Begin Process End
Queste tre parole chiave sono fasi che potete dichiarare all’interno della vostra funzione.
- Begin inizializzerà alcuni passi all’inizio
- Process processerà ogni oggetto come ricevuto
- End può eseguire la pulizia.
Questo è particolarmente utile se volete che la vostra funzione supporti l’elaborazione degli input dalla pipeline.
Questo può essere difficile da capire in teoria, quindi ecco un esempio che ne dimostra l’uso.
function Get-PipelineBeginEnd { param ( $SomeInput ) begin { "Begin: The input is $SomeInput" } process { "The value is: $_" } end { "End: The input is $SomeInput" }}#Get-PipelineBeginEnd1, 2, 3 | Get-PipelineBeginEnd -SomeInput 'Test'
Quando eseguite il codice sopra, notate che Begin viene eseguito una volta, così come End. Process viene eseguito per ogni elemento passato in esso e Process ha accesso all’oggetto corrente nella pipeline.
Logica della funzione
La logica contenuta in una funzione PowerShell non è diversa da quella di uno script. Qui è dove scriverai la logica di base che esegue il compito a cui la tua funzione è destinata. Questo è stato trattato negli episodi 1-10 di questo corso. Puoi anche vedere un esempio completo dal vivo nell’episodio PowerShell Scripts.
Ritorno di funzione
Non tutte le funzioni restituiscono qualcosa quando vengono eseguite. Se la vostra funzione restituirà qualcosa, potete opzionalmente usare return. Tenete a mente che quando usate return, tutte le ulteriori azioni nella funzione si fermeranno e la funzione finirà.
function Get-Total { param ( $Number1, $Number2 ) $total = $Number1 + $Number2 return $total}Get-Total -Number1 2 -Number2 2
Nell’esempio precedente questa semplice funzione contiene due parametri di tipo integer. La logica della funzione somma i due numeri e restituisce il numero intero all’utente.
La tua prima funzione PowerShell
Guarda la funzione PowerShell qui sotto. Notate che il layout aderisce a quello che abbiamo coperto in precedenza. Notate anche che la sezione di aiuto fornisce una grande quantità di dettagli sullo scopo e sull’uso della funzione.
<#.SYNOPSIS Returns your public IP address..DESCRIPTION Queries the ipify Public IP Address API and returns your public IP..EXAMPLE Get-PublicIP Returns the public IP..OUTPUTS System.String.NOTES https://github.com/rdegges/ipify-api#>function Get-PublicIP { $uri = 'https://api.ipify.org' try { $invokeRestMethodSplat = @{ Uri = $uri ErrorAction = 'Stop' } $publicIP = Invoke-RestMethod @invokeRestMethodSplat } catch { Write-Error $_ } return $publicIP}#Get-PublicIP
Come la logica effettiva di questa funzione è abbastanza semplice, potrebbe essere tentato di lasciarla come uno script. Notate però che questo fa una cosa specifica, e la fa bene. Ora potreste incorporare questa funzione in altre logiche avanzate, invece di dover fare riferimento o importare uno script. Anche altri utenti nel vostro ambiente potrebbero iniziare ad utilizzare questa funzione una volta che hanno familiarizzato con essa.
Scopo della funzione
Come la maggior parte dei linguaggi PowerShell ha regole di scoping per le variabili. Quando una variabile è all’interno di una funzione, non sarete più in grado di “vedere” il suo valore. Ecco un esempio di questo comportamento:
function Get-NumberTimesTwo { param ( $Number ) $total = $Number * 2 return $total}#Get-NumberTimesTwoGet-NumberTimesTwo -Number 2
La funzione si comporta come previsto e moltiplica correttamente un numero per due. Nella vostra console, però, provate a vedere qual è il valore di $totale. Non ci riuscirete. Questo perché $totale è limitato alla funzione, e non alla vostra sessione attiva della console.
Questo può confondere le persone nuove a PowerShell e può rendere più difficile scrivere funzioni. Ci sono un paio di strategie per affrontare questo problema.
Potreste scrivere la maggior parte della vostra logica in un formato di tipo script, testando le variabili mentre procedete. Una volta che siete sicuri che la logica stia funzionando come previsto, potreste poi avvolgere la logica all’interno di una funzione.
In alternativa, potete usare Write-Host, Write-Output, o meglio ancora Write-Debug per vedere cosa sta succedendo con le vostre variabili all’interno della vostra funzione!
function Get-NumberTimesTwo { param ( $Number ) $total = $Number * 2 Write-Debug $total return $total}#Get-NumberTimesTwoGet-NumberTimesTwo -Number 2 -Debug
Nota che con il debug switch abbiamo accesso al valore dentro $total per assicurarci che la nostra logica stia facendo ciò che vogliamo.
Esempio di chiusura
Ecco un esempio di chiusura più grande di due funzioni PowerShell che vi permetterà di navigare nel popolare sito web reddit usando PowerShell!
Visitate il link GitHub gist qui sotto per accedere al codice e caricarlo nella vostra console.
https://gist.github.com/techthoughts2/cd2b720c9b291510cbd643e6ca73e05f
Mentre esplorate queste funzioni provate a rispondere alle seguenti domande:
- Delle due funzioni, qual è la funzione principale?
- Sono funzioni standard o avanzate?
- Quale funzione supporterà l’input pipeline?
Additional Reading
- Functions
- Parameters
- Functions Advanced
- Functions Advanced Parameters
- PowerShell Approved Verbs
- CmdletBindingAttribute
Series Navigation << PowerShell ScriptsManage Cloud with PowerShell >>