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."
}
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
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:
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
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:
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 Sì, 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
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
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
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")
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
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.
Scopri di più su questo argomento
Powershell Elimina il file se esiste
PowerShell Write to File: "Out-File" e Tecniche di Output del File
Come creare nuovi utenti di Active Directory con PowerShell
Come eseguire uno script PowerShell
Cos'è PowerShell? Una guida completa alle sue funzionalità e utilizzi