Magic Quadrant™ per la gestione degli accessi privilegiati 2025: Netwrix riconosciuta per il quarto anno consecutivo. Scarica il report.

Piattaforma
Centro risorseBlog
Funzioni negli script di PowerShell

Funzioni negli script di PowerShell

Feb 12, 2025

Le funzioni di PowerShell raggruppano codice riutilizzabile in unità modulari e gestibili che semplificano la scrittura di script e riducono gli errori. Definite con la parola chiave function , possono includere parametri, accettare input da pipeline e comportarsi come cmdlet utilizzando [CmdletBinding()]. Le funzioni supportano funzionalità avanzate come la gestione degli errori con Try/Catch, output dettagliato e di debug, e organizzazione in moduli. Le migliori pratiche includono la denominazione significativa, il design modulare, il ritorno di oggetti e la documentazione tramite aiuto basato su commenti.

Una funzione PowerShell è un blocco di codice progettato per eseguire un compito specifico. Una volta creata e testata, può essere utilizzata in più script, riducendo lo sforzo di codifica e il rischio di errori. Utilizzare funzioni ben nominate rende inoltre gli script più facili da leggere e mantenere. E poiché le funzioni possono restituire valori che possono essere utilizzati come input per altre funzioni o blocchi di codice, facilitano la costruzione di operazioni complesse.

Questo articolo spiega tutto ciò che devi sapere per iniziare ad utilizzare le funzioni di PowerShell, incluse le migliori pratiche importanti, e fornisce anche orientamenti per addentrarsi in opzioni più avanzate.

Iniziare con le funzioni di PowerShell

Come creare una funzione in PowerShell

Per definire una funzione, si utilizza la parola chiave function. La sintassi di base è la seguente: 

      function <Function-Name> { 

    <Code-Block> 
}
      

Il codice all'interno delle parentesi graffe {} verrà eseguito quando la funzione viene chiamata.

Se lo desideri, puoi utilizzare la parola chiave param per specificare i parametri della funzione, insieme ai tipi di dati, valori predefiniti e così via. Ecco la sintassi con i parametri aggiunti: 

      function <Function-Name> { 

    [param( 

        [<ParameterType>]$<ParameterName>, 

        [<ParameterType>]$<ParameterName2> = <DefaultValue> 

    )] 

    <Code-Block> 

}
      

Questo esempio di funzione PowerShell moltiplicherà due numeri e visualizzerà il risultato:

      function Multiply-Numbers { 

    param ( 

        [int]$Number1, 

        [int]$Number2 

    ) 

    $Result = $Number1 * $Number2 

    Write-Output "The multiplication value of $Number1 and $Number2 is $Result." 

}
      
Image

Salvare una Funzione

Per salvare una funzione, basta memorizzarla in un file di script con un.ps1?estensione.

Chiamare una Funzione

Per invocare una funzione in PowerShell, digita il nome della funzione seguito dai parametri nominati necessari. Ad esempio, ecco come chiamare la funzione che abbiamo definito sopra:

      Multiply-Numbers -number1 6 -Number2 8 

      
Image

Esecuzione di una funzione come parte della sessione corrente (Dot-Sourcing)

Il dot-sourcing consente di eseguire uno script PowerShell come se fosse definito direttamente all'interno della sessione della console corrente. Per utilizzare il dot-sourcing, precedere il nome della funzione con un punto e uno spazio (. ) quando la si chiama.

Ad esempio, supponiamo di aver definito la seguente funzione chiamata Add-Numbers: 

      function Add-Numbers { 

    param ( 

        [int]$Number1, 

        [int]$Number2 

    ) 

    $Sum = $Number1 + $Number2 

    Write-Output "The sum of $Number1 and $Number2 is $Sum." 

}
      

Possiamo eseguire il dot-sourcing di questa funzione nella nostra sessione come mostrato qui:

Image

Denominare le Funzioni PowerShell

Per ottenere il massimo valore dalle funzioni di PowerShell, assicurati di seguire queste linee guida quando nomini le tue funzioni.

Usa il formato verbo-sostantivo.

PowerShell fornisce un insieme di cmdlet predefiniti i cui nomi seguono un formato specifico: un verbo che specifica l'azione da eseguire, seguito da un sostantivo che nomina l'oggetto su cui agire. Ad esempio, il cmdlet get-user recupera informazioni su un utente e remove-item elimina un elemento specificato.

Seguire la stessa convenzione di denominazione per le funzioni che si creano è considerata una prassi ottimale. Farlo aiuterà a progettare le funzioni in modo più efficace e a renderle più facili da riutilizzare.

Usa verbi approvati.

PowerShell fornisce un elenco di verbi raccomandati per l'uso nelle funzioni. Per visualizzare l'elenco, esegui semplicemente il seguente cmdlet:

      Get-Verb 

      

Scegli sostantivi descrittivi.

È fondamentale non assegnare a una funzione lo stesso nome di un cmdlet integrato. Un buon metodo per evitare questo problema è non utilizzare sostantivi generici come user e data. Invece, scegliere sostantivi che indichino chiaramente il tipo di dati su cui la funzione agisce. Ad esempio, è facile capire come queste funzioni siano diverse: Get-EmployeeData, Get-UserInfo e Get-ServiceInfo.

Evitare di usare nomi di funzioni per scopi di versionamento.

Aggiungere numeri di versione ai nomi delle funzioni, come Get-UserInfoV2, non è consigliato. Rende gli script più difficili da comprendere e aumenta il rischio di utilizzare versioni obsolete di una funzione. Invece, gestisci il versioning attraverso il tuo sistema di versionamento dei file.

Capacità di funzioni avanzate

Accettazione dell'input della pipeline

È possibile progettare una funzione per accettare input da un'altra funzione o comando tramite una pipeline utilizzando l'attributo ValueFromPipeline.

Per illustrare, creiamo una funzione che elabora una lista di stringhe una per una, converte ogni stringa in maiuscolo e ne mostra i risultati. Per chiarezza, divideremo l'elaborazione delle stringhe in tre blocchi distinti:

  • INIZIO — Questo codice viene eseguito una volta, prima di elaborare qualsiasi input della pipeline. 
  • PROCESSO — Questa sezione viene eseguita per ogni elemento che viene passato alla pipeline, elaborando gli oggetti in ingresso uno per uno.
  • FINE — Questo codice viene eseguito dopo che tutti gli input sono stati elaborati per finalizzare l'output. 
      function Convert-ToUppercase { 

    [CmdletBinding()] 

    param ( 

        [Parameter(ValueFromPipeline = $true, Mandatory = $true)] 

        [string]$InputString 

    ) 

    BEGIN { 

        Write-Verbose "Starting the uppercase conversion process." 

    } 

    PROCESS { 

        if (-not [string]::IsNullOrWhiteSpace($InputString)) { 

            Write-Verbose "Processing string: $InputString" 

            $InputString.ToUpper() 

        } else { 

            Write-Verbose "Skipped empty or null string." 

        } 

    } 

    END { 

        Write-Verbose "Finished processing all strings." 

    } 

}
      

Ecco come potremmo chiamare la nostra funzione per convertire un elenco di stringhe fornite tramite una pipeline:

      "hello", "world", "this", "is", "powershell" | Convert-ToUppercase -Verbose 

      
Image

Si noti che le funzioni leggere chiamate filters possono fornire un modo altamente efficiente per elaborare gli oggetti passati attraverso una pipeline. 

Abilitare una Funzione a Comportarsi come un Cmdlet

Puoi trasformare una funzione di base in una funzione avanzata utilizzando l'attributo CmdletBinding. Così facendo, la funzione si comporterà come un cmdlet, inclusa la compatibilità con i parametri di PowerShell definiti.

Ecco la funzione di base che abbiamo definito in precedenza per sommare due numeri:

      function Add-Numbers { 

    param ( 

        [int]$Number1, 

        [int]$Number2 

    ) 

    $Sum = $Number1 + $Number2 

    Write-Output "The sum of $Number1 and $Number2 is $Sum." 

}
      

Possiamo trasformarlo in una funzione avanzata come segue:

      function Add-Numbers { 

    [CmdletBinding()] 

    param ( 

        [Parameter(Mandatory)] 

        [int]$Number1, 

        [Parameter(Mandatory)] 

        [int]$Number2 

    ) 

    process { 

        # Verbose Output 

        Write-Verbose "Starting addition of $Number1 and $Number2" 

        # Debugging Output 

        Write-Debug "Debugging: Ensuring numbers are valid integers" 

        # Perform the Addition 

        try { 

            $Result = $Number1 + $Number2 

            Write-Output $Result 

        } catch { 

            # Handle errors with error stream 

            Write-Error "An error occurred while performing the addition." 

        } 

        # Verbose Completion Message 

        Write-Verbose "Addition completed successfully" 

    } 

}
      

Richiedi una prova gratuita di Netwrix Auditor

Costruzione di Moduli Funzionali

Un modulo di funzione è un file con estensione .psm1 che contiene una raccolta di funzioni correlate. Organizzare le funzioni in moduli facilita la riutilizzabilità e la manutenzione.

Per creare un modulo di funzione, basta creare un file di testo, incollare le tue funzioni e salvare il file con l'estensione .psm1 nella directory C:\Program Files\WindowsPowerShell\Modules. Ad esempio, potremmo creare un modulo con funzioni aritmetiche come la funzione Add-Numbers definita in precedenza.

Per importare il modulo nella tua sessione di PowerShell, usa il comando Import-Module, come mostrato qui: 

Image

Gestione degli errori

PowerShell offre diverse tecniche di gestione degli errori per aiutarti a gestire senza problemi problemi che altrimenti potrebbero interrompere l'esecuzione di una funzione con un errore, come un tentativo di divisione per zero.

Blocchi Try/Catch/Finally

Quando sai che una certa condizione potrebbe causare un problema, puoi utilizzare i blocchi Try, Catch e Finally nella tua funzione per gestire quella condizione con eleganza:

  • Prova — Questo blocco contiene codice che potrebbe generare un errore (come un'operazione di divisione). Se non si verifica alcun errore, il blocco Catch non verrà eseguito. 
  • Catch — Se si verifica un errore nel blocco Try, il blocco Catch lo gestirà catturando ed elaborando i dettagli dell'errore.
  • Infine — Questo blocco è opzionale. Se presente, viene eseguito dopo i blocchi Try e Catch, indipendentemente dal fatto che si sia verificato un errore.

-ErrorAction Parametro

Il parametro -ErrorAction consente di specificare come gestire gli errori per una determinata funzione. I valori possibili sono:

  • Continua — Visualizza un messaggio di errore e continua.
  • Stop — Interrompe l'esecuzione dello script quando si verifica un errore.
  • SilentlyContinue — Sopprimi il messaggio di errore e continua l'esecuzione.
  • Richiedi — Chiedi all'utente come gestire l'errore con opzioni come , No e Riprova.
  • Ignora — Ignora completamente l'errore senza nemmeno visualizzare un messaggio.

Di seguito sono riportati alcuni esempi del parametro -ErrorAction

      Remove-Item "C:\path\to\nonexistentfile.txt" -ErrorAction SilentlyContinue 

 
Get-Process -Name "Notepad" -ErrorAction Stop
      

Variabile $ErrorActionPreference

La variabile $ErrorActionPreference controlla come vengono gestiti globalmente gli errori per tutti i cmdlet in una sessione. Questa variabile può essere impostata per influenzare il comportamento della gestione degli errori in tutti i comandi, a meno che non venga sovrascritta dal parametro -ErrorAction.

Esempio dettagliato

Di seguito è riportato un esempio che utilizza diversi metodi di gestione degli errori:

  • La variabile $ErrorActionPreference imposta la preferenza globale per la gestione degli errori su stop, quindi quando si verifica un errore che non è altrimenti gestito, l'esecuzione si interromperà.
  • I blocchi Try/Catch gestiscono con eleganza il potenziale errore della divisione per zero senza interrompere l'esecuzione. Il blocco Try esegue le operazioni matematiche. Se si imbatte nella divisione per zero, il processo passa al blocco Catch che stampa un messaggio di errore.
  • Il blocco Finally verrà eseguito indipendentemente dall'occorrenza di un errore, stampando un messaggio che indica che le operazioni sono terminate.
      # Set global error action preference to 'Stop' to immediately halt on errors 

$ErrorActionPreference = 'Stop' 

function Perform-MathOperations { 

    param ( 

        [int]$Num1, 

        [int]$Num2 

    ) 

    try { 

        # Performing addition 

        Write-Host "Performing addition: $Num1 + $Num2" 

        $additionResult = $Num1 + $Num2 

        Write-Host "Addition Result: $additionResult" 

        # Checking for division by zero before performing division 

        if ($Num2 -eq 0) { 

            throw "Division by zero is not allowed." 

        } 

        # Performing division 

        Write-Host "Performing division: $Num1 / $Num2" 

        $divisionResult = $Num1 / $Num2 

        Write-Host "Division Result: $divisionResult" 

    } 

    catch { 

        # Catching any error that occurs in the try block 

        Write-Host "An error occurred: $_" 

        Write-Host "Error Type: $($_.Exception.GetType().Name)" 

    } 

    finally { 

        # This block always runs regardless of error occurrence 

        Write-Host "Finished performing math operations." 

    } 

}
      

Lo screenshot qui sotto mostra il risultato della chiamata di questa funzione in due modi. Prima, la chiamiamo con un input valido:

Perform-MathOperations -Num1 10 -Num2 2

Poi lo chiamiamo con un input che risulterà in un tentativo di divisione per zero:

Esegui-MathOperations -Num1 10 -Num2 0

Image

Risoluzione dei problemi delle tue funzioni

Puoi visualizzare messaggi che forniscono vari livelli di dettaglio durante l'esecuzione di una funzione utilizzando Write-output (o Write-host), Write-Verbose e Write-Debug. Queste informazioni possono aiutarti a tracciare il percorso di esecuzione passo dopo passo per individuare comportamenti inaspettati.

Ad esempio, la seguente schermata mostra come potremmo rivedere la nostra funzione di base Add-Numbers per fornire dettagli di risoluzione dei problemi. Nota che per impostazione predefinita, il flusso di messaggi dettagliati non viene visualizzato, quindi dobbiamo utilizzare -Verbose quando invochiamo la funzione.

      Add-Numbers -Number1 5 -Number2 10 -Verbose 

      
Image

Analogamente, Write-Debug i messaggi non vengono visualizzati nella console per impostazione predefinita, ma è possibile visualizzarli includendo -Debug quando si esegue la funzione: 

Add-Numbers -Number1 5 -Number2 10 -Debug

Image

Migliori Pratiche

  • Progettare ogni funzione affinché svolga un solo compito. Ciò le rende più facili da testare, utilizzare e mantenere.
  • Progetta le funzioni in modo modulare in modo che possano essere riutilizzate in diversi script.
  • Quando si utilizzano parametri, specificare i loro valori predefiniti.
  • Includete commenti dettagliati nelle vostre funzioni. Questo aiuto basato sui commenti faciliterà il debugging e il riutilizzo delle funzioni.
  • Fai in modo che le tue funzioni restituiscano oggetti piuttosto che output formattato per migliorare la riusabilità.

Esempio aggiuntivo

La seguente funzione illustra molte delle capacità discusse in precedenza, incluse la gestione degli errori:

      # Function: Backup-Files 

# Description: Backs up files from a source directory to a backup directory. 

function Backup-Files { 

    param ( 

        [Parameter(Mandatory = $true)] 

        [string]$SourcePath, # The directory containing the files to back up 

        [Parameter(Mandatory = $true)] 

        [string]$BackupPath, # The directory where files will be backed up 

        [string[]]$Extensions = @("*") # File extensions to back up (default: all files) 

    ) 

    # Check if the source path exists 

    if (-not (Test-Path -Path $SourcePath)) { 

        Write-Error "Source path '$SourcePath' does not exist." 

        return 

    } 

    # Create the backup directory if it does not exist 

    if (-not (Test-Path -Path $BackupPath)) { 

        Write-Output "Creating backup directory at '$BackupPath'..." 

        New-Item -ItemType Directory -Path $BackupPath | Out-Null 

    } 

    # Get files matching the specified extensions 

    foreach ($extension in $Extensions) { 

        $files = Get-ChildItem -Path $SourcePath -Filter "*.$extension" -File -ErrorAction SilentlyContinue 

        foreach ($file in $files) { 

            $destination = Join-Path -Path $BackupPath -ChildPath $file.Name 

            Write-Output "Backing up file: $($file.FullName) -> $destination" 

            Copy-Item -Path $file.FullName -Destination $destination -Force 

        } 

    } 

    Write-Output "Backup completed successfully." 

}
      

Possiamo chiamare questa funzione per eseguire il backup di tutti i file, oppure solo di estensioni di file selezionate come mostrato qui:

      Backup-Files -SourcePath "D:\Office\project" -BackupPath "D:\Backup" -Extensions @("csv", "txt") 

      
Image

Conclusione

Le funzioni in PowerShell offrono un approccio strutturato alla scrittura di script che migliora la modularità, la riutilizzabilità e la manutenibilità. Sentiti libero di sperimentare con tutto il codice di esempio fornito in questo articolo. Mentre inizi a creare le tue funzioni, assicurati di adottare le migliori pratiche per la denominazione e l'utilizzo.

Condividi su

Scopri di più

Informazioni sull'autore

Asset Not Found

Tyler Reese

Vicepresidente della Gestione Prodotti, CISSP

Con più di due decenni nel settore della sicurezza del software, Tyler Reese conosce intimamente le sfide di identità e sicurezza in rapida evoluzione che le aziende affrontano oggi. Attualmente, ricopre il ruolo di direttore del prodotto per il portfolio di Netwrix Identity and Access Management, dove le sue responsabilità includono la valutazione delle tendenze di mercato, la definizione della direzione per la linea di prodotti IAM e, in ultima analisi, la soddisfazione delle esigenze degli utenti finali. La sua esperienza professionale spazia dalla consulenza IAM per le aziende Fortune 500 al lavoro come architetto aziendale di una grande compagnia diretta al consumatore. Attualmente detiene la certificazione CISSP.