Guida alle Best Practice per Scripting PowerShell

Cosa

Questo articolo fornisce una guida completa alle best practice per lo scripting in PowerShell, con focus su struttura del codice, formattazione dell’output, gestione degli errori, ottimizzazione delle prestazioni e misure di sicurezza.

Perché

Seguire le best practice nello scripting PowerShell garantisce script leggibili, manutenibili, sicuri ed efficienti. Riduce il debito tecnico, migliora la collaborazione e minimizza i rischi negli ambienti di produzione.

Come

Progettazione di Strumenti e Controller

Decidi se stai creando uno "Strumento" o un "Controller"

  • Strumento: Funzioni/moduli riutilizzabili.
  • Controller: Automatizza un’attività specifica, non destinato al riutilizzo.

Rendi il codice modulare

  • Usa funzioni e moduli di script per massimizzare la riutilizzabilità.

Usa convenzioni di denominazione standard

  • Segui il formato Verbo-Sostantivo con verbi approvati da PowerShell (Get-Verb).

Standardizza i nomi dei parametri

  • Utilizza nomi come $ComputerName invece di prefissi personalizzati.

Gli strumenti devono restituire dati grezzi

  • Fornisci dati minimamente elaborati per una maggiore flessibilità.

I controller devono restituire dati formattati

  • Formatta l’output per report user-friendly.

Esempio

function Get-DiskInfo {
    param ([string]$ComputerName)
    Get-WmiObject Win32_LogicalDisk -ComputerName $ComputerName
}

Evita di reinventare la ruota

Usa cmdlet integrati come Test-Connection invece di creare funzioni personalizzate.

# Consigliato
Test-Connection $ComputerName -Quiet

Scrittura dei Blocchi di Parametri

Scrivi sempre la documentazione di aiuto

Includi commenti con .SYNOPSIS, .DESCRIPTION e almeno un .EXAMPLE.

function Test-Help {
    <#
        .SYNOPSIS
            Esempio di corretta documentazione.
        .EXAMPLE
            Test-Help -MandatoryParameter "Esempio"
            Esegue la funzione con un parametro obbligatorio.
    #>
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [Alias("MP")]
        [String]$MandatoryParameter
    )
}

Usa [CmdletBinding()]

Abilita parametri comuni come -Verbose, -Debug, -ErrorAction.

Supporta -WhatIf e -Confirm

Per comandi che modificano lo stato, usa SupportsShouldProcess.

[CmdletBinding(SupportsShouldProcess, ConfirmImpact = "Medium")]
param ([switch]$Force)

Tipizzazione forte dei parametri

Definisci sempre i tipi per chiarezza e validazione.

param (
    [string]$Name,
    [int]$Count
)

Usa [switch] correttamente

  • Il valore predefinito è $false.
  • Usalo come booleano, evitando logiche complesse.

Formattazione dell’Output

Evita Write-Host se non necessario

Preferisci Write-Verbose, Write-Debug o Write-Output a seconda del contesto.

Usa Write-Progress per aggiornamenti di avanzamento

Write-Progress -Activity "Elaborazione" -Status "50% completato" -PercentComplete 50

Usa file di formattazione per oggetti personalizzati

Definisci file .format.ps1xml invece di formattazioni inline.

Restituisci un solo tipo di oggetto alla volta

Utilizza [OutputType()] ed evita la mescolanza di tipi.


Best Practice per la Gestione degli Errori

Usa -ErrorAction Stop con i cmdlet

Forza gli errori per poterli gestire con try-catch.

try {
    Get-Item "C:\PercorsoNonValido" -ErrorAction Stop
} catch {
    Write-Warning "Elemento non trovato."
}

Usa $ErrorActionPreference per operazioni non-cmdlet

Impostalo temporaneamente su 'Stop' per operazioni rischiose.

Evita flag e $? per la gestione degli errori

Preferisci blocchi strutturati try-catch.

Copia subito $Error[0] o $_ all’interno di catch

catch {
    $errorDetails = $_
    Write-Error "Si è verificato un errore: $($errorDetails.Exception.Message)"
}

Ottimizzazione delle Prestazioni

PERF-01 Misura le prestazioni quando necessario

Utilizza Measure-Command per confrontare soluzioni.

Measure-Command {
    foreach ($item in $data) { Process-Item $item }
}

PERF-02 Bilancia leggibilità e prestazioni

  • Per piccoli dataset, privilegia la leggibilità.
  • Per grandi volumi, considera streaming o tecniche .NET.

Leggibile ma meno performante:

$content = Get-Content -Path file.txt
foreach ($line in $content) {
    Do-Something -Input $line
}

Ottimizzato:

Get-Content -Path file.txt | ForEach-Object {
    Do-Something -Input $_
}

Alta performance con .NET:

$sr = New-Object System.IO.StreamReader "file.txt"
while ($sr.Peek() -ge 0) {
    $line = $sr.ReadLine()
    Do-Something -Input $line
}

PERF-03 Preferisci le strutture del linguaggio ai cmdlet

  • Strutture (foreach) > Metodi .NET > Script > Cmdlet/Pipeline.
  • Misura sempre prima di ottimizzare.

Best Practice di Sicurezza

Usa sempre PSCredential per le credenziali

Evita password in chiaro.

param (
    [System.Management.Automation.PSCredential]
    [System.Management.Automation.Credential()]
    $Credential
)

Per API:

$Insecure.SetPassword($Credential.GetNetworkCredential().Password)

Usa SecureString per dati sensibili

$Secure = Read-Host -Prompt "Inserisci dati sicuri" -AsSecureString

Conversione sicura:

$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Secure)
$PlainText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)

Salva le credenziali in modo sicuro

Get-Credential | Export-CliXml -Path C:\secure\cred.xml
$Credential = Import-CliXml -Path C:\secure\cred.xml

Salva stringhe criptate

ConvertFrom-SecureString -SecureString $Secure | Out-File -Path "${Env:AppData}\secure.bin"
$Secure = Get-Content -Path "${Env:AppData}\secure.bin" | ConvertTo-SecureString

Conclusione

Seguendo queste best practice di PowerShell in termini di design, documentazione, gestione dell’output, errori, prestazioni e sicurezza, potrai creare script robusti, efficienti e facilmente manutenibili. Cerca sempre il giusto equilibrio tra leggibilità, performance e sicurezza per offrire soluzioni di automazione di alta qualità.

タイトルとURLをコピーしました