venerdì 24 marzo 2017

TUTORIAL POWERSHELL - PARTE 6 - FUNZIONI

Tutorial introduttivo all'utilizzo di PowerShell, a prima vista una estensione del prompt dei comandi di Microsoft Windows ma che in realtà è molto di più.






Lista completa articoli su Tutorial PowerShell [link]

Function

Per quanto gli Script visti nell'articolo precedente [link] siano utili, non dovrebbero essere utilizzati come libreria di funzionalità, per fare questo è necessario introdurre negli Script il concetto di Function.

Una Function, o funzione, equivale alle funzioni negli altri Linguaggi di Programmazione: un qualcosa che, partendo da un input opzionale, esegue delle operazioni e può produrre un output.

Nell'articolo precedente [link] abbiamo creato uno script "hello-qualcosa", vediamo come trasformarlo in una funzione:
function hellosomething{
   Param($something)
   Write-Output "hello $something"
}

Come possiamo vedere è stato sufficiente aggiungere la parola chiave Function, seguita dal nome della funzione, e racchiudere il codice dello Script fra parentesi graffe.

Nota: Uno degli errori più comuni dei principianti è quello di inserire parentesi tonde dopo il nome della funzione, questo causa un fraintendimento con l'interprete dei comandi che si aspetta la definizione di un array.

I principali vantaggi nello scrivere Function invece di Script sono:
  • Si possono scrivere più funzioni in un unico file Script
  • Possono essere utilizzate solo alcune delle funzioni del file Script
  • Aumenta la portabilità e riusabilità del codice 
  • Le funzioni sono esposte a PowerShell e sono automaticamente associate al cmdlet Get-Help.
Per eseguire una funzione è necessario eseguire lo script, una volta eseguito sarà sufficiente richiamare il nome della funzione nella console:

Nota: come abbiamo visto nel precedente articolo [link] per utilizzare le variabili all'esterno dello scope dello script è necessario aggiungere un carattere punto (.) prima dello script, analogamente per utilizzare una funzione all'esterno dello scope dello Script/Function è necessario eseguire il codice con il carattere punto (.) davanti. PowerShell ISE è esente da questa caratteristica.

Best Practice - Nomenclatura

Durante l'introduzione ai cmdlet [link] è stato visto come i comandi siano strutturati com:
verbo-complemento

Per questo motivo, è una buona pratica scrivere le proprie funzioni personalizzate secondo la medesima struttura. Seguendo questa logica, la funzione hellosomething potrebbe essere rinominata Get-HelloSomething.

Nota: Per una lista completa dei Verbi utilizzabili digitare il seguente cmdlet PowerShell:
Get-Verb

Commenti

Nei Linguaggi di Programmazione o di Scripting, un commento è una linea di testo inserita in un codice sorgente che viene ignorata dal compilatore e dall'interprete. Inizialmente i commenti erano utilizzati esclusivamente per comunicare al programmatore alcune informazioni (commenti, problemi, istruzioni..). Con il passare del tempo i commenti hanno assunto più valore con l'introduzione dei generatori di documentazione (Come il software SqlDocGen di Programmazione Applicata [link]) basati su commenti, particolari software in grado di produrre un documento di testo andando ad analizzare i commenti di un codice sorgente.

Per scrivere un commento è sufficiente inserire il carattere cancelletto (#) come primo carattere della linea.
#this is a comment

Oltre alle singole linee di commento, è possibile specificare un gruppo di linee come commento aggiungendo in cima e in fondo alla sezione i caratteri cancelletto fra tag (<#  #>):
<#
this is a 
comment section
#>

Help Personalizzato

Come abbiamo accennato in un precedente articolo [link], uno dei vantaggi nell'utilizzare funzioni rispetto agli script, è l'esposizione automatica della funzione al cmdlet Get-Help. Vediamo quale output restituisce sulla nostra funzione:


Anche se non è stato specificato alcun testo di help, il cmdlet Get-Help cerca in ogni modo di fornire più informazioni possibili. Può essere facilitato il compito inserendo un help personalizzato:
<#
.Synopsis
Say Hello to what is passed as parameter
.DESCRIPTION
    This function print on the Output Stream the sentence "hello" followed by a blank
    space then the string passed as first parameter. Further parameters are ignored.
.EXAMPLE
    Get-HelloSomething world
    hello world
.INPUTS
    Input as object. Does not accept pipeline input. 
.OUTPUTS
    Output as string. 
#>
function Get-HelloSomething{
    Param($something)
    Write-Output "hello $something"
}


L'Help Personalizzato appena inserito è formato dalle seguenti parti:
  • Synopsis, breve descrizione del comando
  • Description, descrizione dettagliata del comando
  • Example, esempio di utilizzo (anche più di uno)
  • Inputs, parametri previsti e indicazione se sono accettati parametri pipeline
  • Outputs, output della cmdlet.
Esistono altre parti che possono essere personalizzate dell'help, per ulteriori dettagli digitare su PowerShell il seguente comando:
Get-Help about_comment_based_help

Attenzione! quando si scrivono commenti per l'Help Personalizzato è necessario prestare molta attenzione a rispettare la sintassi giusta e ricordare che non è possibile inserire sezioni con nomi a piacere.

Parametri Espliciti

Quando abbiamo trasformato lo script "hello-qualcosa" in una funzione, non è stato modificato il metodo di ottenimento dei parametri, tuttavia quando si utilizzano le funzioni è possibile specificare un numero e un tipo di dato preciso da ricevere come parametro.

Esempio: realizziamo una piccola funzione di somma di due numeri interi:
function Math-Add{
    Param([int] $a, [int]$b)
    $res=$a+$b
    Write-Output $res
}

Se si prova ad eseguire la funzione passando come parametro delle stringhe si ottiene il seguente errore:


Parametri Flag

Oltre ai classici parametri tipizzati è possibile scrivere funzioni che si aspettino un parametro di tipo flag. Un parametro di tipo flag è un parametro che viene passato al cmdlet nella forma "-flag" come il -? utilizzato per mostrare l'help di un cmdlet che abbiamo visto nella parte 3 di questo tutorial [link].

I parametri flag sono di tipo [switch] e hanno un valore booleano. Esempio: realizziamo una piccola variante di hellosomething in modo tale che venga scritto tutto maiuscolo se specificato il flag di -ScreamIt.
function Get-HelloSomething{
    Param([string]$something,[switch]$screamit)
    if($screamit){
        Write-Output $something.ToUpper()
    }else{
        Write-Output $something
    }
}


Parametri Default

Potrebbe non essere necessario specificare un parametro per una funzione e quindi utilizzare un valore predefinito. Per impostare un parametro ad un valore di default è sufficiente assegnare un valore all'interno della chiamata del metodo Param():
function Get-HelloSomething{
    Param([string]$something="world")
    Write-Output "hello $something"
}

Return

L'ultima differenza fondamentale con altri linguaggi di programmazione sta nel concetto di valore di ritorno. In PowerShell non esiste un valore di ritorno esplicito e non è necessario utilizzare una parola chiave di ritorno.

Gli esempi seguenti hanno infatti lo stesso output:

return 1
1
1 return
Write-Output 1

Questo perchè l'output di PowerShell si basa sul concetto di Stream.

Stream

L'output di PowerShell si basa sul concetto di Stream, un flusso di dati sempre a disposizione all'interno di una sessione. In PowerShell esistono quattro tipi di Stream:
  1. Output, il messaggio viene scritto nella console semplicemente.
  2. Error, il messaggio viene interpretato come errore, viene evidenziato di rosso e vengono mostrate informazioni riguardo l'errore.
  3. Warning, il messaggio viene interpretato come avvertimento, viene evidenziato di giallo.
  4. Debug, il messaggio viene interpretato come debug, non viene scritto nella console
  5. Verbose, il messaggio viene interpretato come verbose, non viene scritto nella console.
  6. Information, il messaggio viene interpretato come info (introdotto con PowerShell 5.0)
Dalla lista, si può notare come Debug e Verbose non vengano scritti nella console. Per abilitare la visualizzazione dei messaggi di Debug è necessario modificare il valore della variabile $debugpreference="continue" mentre per abilitare il Verbose deve essere impostato il valore della variable $verbosepreference="continue".

Conclusione

Abbiamo visto come incapsulare le funzionalità degli Script in Function ed utilizzarle comodamente dalla console senza dover ogni volta chiamare uno Script. Nel prossimo articolo [link] vedremo come realizzare una libreria di funzioni personalizzata che, in PowerShell, viene chiamata Modulo.


Nessun commento:

Posta un commento