run powershell script from powershell

run powershell script from powershell

Immagina questa scena: sono le tre del mattino e un intero reparto IT è bloccato perché un processo di migrazione dati automatizzato si è fermato a metà. Il responsabile ha scritto un controller principale che dovrebbe orchestrare dieci altri file .ps1, convinto che richiamare Run PowerShell Script From PowerShell sia un'operazione banale, quasi scontata. Invece, si ritrova con variabili che spariscono nel nulla, permessi negati che non appaiono nei log e una memoria RAM che si satura senza un motivo apparente. Ho visto questa situazione ripetersi in aziende di ogni dimensione, dalle startup ai colossi bancari, dove la presunzione di saper concatenare due file porta a perdite economiche stimate in migliaia di euro per ogni ora di fermo tecnico. Il problema non è lo strumento, ma la totale mancanza di comprensione di come i contesti di esecuzione interagiscono tra loro quando decidi di avviare un processo dall'interno di un altro.

L'illusione del copia e incolla nel Run PowerShell Script From PowerShell

Molti sistemisti pensano che basti incollare il percorso di un file per farlo funzionare come se lo stessero digitando a mano. Non è così. Quando decidi di eseguire Run PowerShell Script From PowerShell, la prima trappola in cui cadi è la gestione degli scope. Se lanci un comando usando l'operatore dot sourcing, ovvero il punto seguito dallo spazio e dal percorso, stai letteralmente iniettando il codice nel tuo ambiente attuale. Questo significa che se lo script chiamato modifica una variabile chiamata $Data, quella modifica sovrascriverà la variabile omonima nel tuo script principale. Ho visto database svuotati perché un sottoscript di pulizia usava nomi di variabili troppo generici, sovrascrivendo i puntatori di produzione del chiamante.

La soluzione non è smettere di farlo, ma capire quando isolare. Se non hai bisogno che il file chiamato lasci tracce nel tuo ambiente, devi usare l'operatore di chiamata &. Questo crea un nuovo ambito di visibilità. Le variabili create lì dentro muoiono lì dentro. Sembra un dettaglio da poco, ma risparmia giorni di caccia al bug quando i tuoi flussi di automazione superano le cento righe di codice.

Il disastro dei percorsi relativi

Un altro errore che costa caro è l'uso dei percorsi relativi. Lo script funziona perfettamente sul tuo PC perché lo lanci dalla cartella C:\Scripts, ma fallisce miseramente quando l'Utilità di pianificazione lo esegue da C:\Windows\System32. Lo script principale parte, ma non trova i suoi compagni di viaggio. Invece di usare percorsi come .\subscript.ps1, devi sempre ricostruire il percorso assoluto usando $PSScriptRoot. Questa variabile automatica ti dice esattamente dove si trova il file che stai eseguendo in quel momento, permettendoti di puntare agli altri file con precisione chirurgica, indipendentemente da dove viene invocato il processo.

Gestire gli errori senza farsi accecare dal silenzio

Ho visto amministratori di sistema convinti che basti un Try-Catch nello script principale per dormire sonni tranquilli. La realtà è molto più brutale. Quando effettui un Run PowerShell Script From PowerShell, gli errori che accadono nel file secondario spesso non risalgono al chiamante nel modo in cui ti aspetti. Se il sottoscript va in errore ma non termina il processo, il tuo script principale continuerà a girare come se nulla fosse accaduto, convinto che tutto sia andato a buon fine.

In un caso reale in un centro logistico, uno script di etichettatura non riusciva a connettersi alla stampante. Poiché l'errore non veniva propagato correttamente al controllore principale, il sistema continuava a segnare gli ordini come "spediti" nel database, anche se nessuna etichetta veniva stampata. Il risultato? Centinaia di pacchi fermi e una giornata di lavoro persa per riconciliare i dati. La soluzione tecnica è l'uso di $ErrorActionPreference = 'Stop' all'inizio di ogni file e la verifica manuale di $LASTEXITCODE se stai chiamando processi esterni. Non puoi fidarti del fatto che PowerShell "capisca" che qualcosa è andato storto; devi costringerlo a fermarsi e a urlare.

La trappola delle autorizzazioni e dei contesti di sicurezza

Non puoi dare per scontato che i privilegi si trasferiscano magicamente. Se lo script A gira come amministratore e chiama lo script B, quest'ultimo dovrebbe ereditare i permessi, ma cosa succede se lo script B deve accedere a una risorsa di rete mappata? Le unità mappate come Z: sono specifiche per la sessione utente. Se il tuo processo di automazione gira sotto un account di servizio, quel Z: non esiste. Ho visto decine di ore buttate a cercare di capire perché un file non veniva trovato, solo per scoprire che l'utente che eseguiva il test manuale aveva i dischi mappati, mentre il sistema di produzione no.

Usa sempre i percorsi UNC (come \\Server\Share) per evitare queste ambiguità. Inoltre, presta attenzione alla Execution Policy. Molti risolvono il problema impostando Set-ExecutionPolicy Unrestricted su tutto il server, aprendo una falla di sicurezza grande quanto un portone. La strategia corretta è firmare i propri file con un certificato interno o, al limite, usare il parametro -ExecutionPolicy Bypass solo per quella specifica chiamata, limitando l'esposizione al rischio.

Prima e Dopo: come cambia la stabilità di un flusso di lavoro

Vediamo come si presenta la differenza tra un approccio amatoriale e uno professionale in un contesto di aggiornamento server notturno.

L'approccio sbagliato si presenta con uno script principale che contiene una lista di stringhe con i nomi degli altri file. Il programmatore usa un ciclo foreach e invoca i file semplicemente scrivendo il loro nome. Non c'è cattura dell'output, non c'è log e non c'è gestione degli errori. Se il terzo script della lista fallisce perché il server è offline, il quarto parte comunque, magari cercando di scrivere dati su un sistema che non è stato preparato. Al mattino, il log è vuoto o contiene solo "File non trovato", senza indicare quale, quando o perché.

L'approccio corretto trasforma questo caos in un processo solido. Lo script principale definisce prima di tutto una funzione di logging che scrive sia su console che su un file rotativo. Ogni chiamata a un file esterno viene avvolta in un blocco Try-Catch. Prima di eseguire il codice, il sistema verifica l'esistenza del file tramite Test-Path. L'invocazione avviene tramite & $PercorsoAssoluto e, subito dopo, viene controllato lo stato di uscita. Se un passaggio critico fallisce, lo script principale invia un'email di allerta e interrompe l'intera catena, lasciando il sistema in uno stato sicuro invece di procedere al buio. Questa differenza di metodo è ciò che distingue un sistemista che passa i weekend a sistemare disastri da uno che può permettersi di spegnere il telefono.

Le prestazioni nascoste dietro le sessioni multiple

Quando il carico di lavoro aumenta, la tentazione è quella di aprire molteplici sessioni per velocizzare le operazioni. Avviare processi separati consuma risorse. Ogni volta che lanci un nuovo ambiente di esecuzione, Windows deve allocare memoria per caricare l'intero motore di PowerShell, i moduli necessari e le impostazioni del profilo. Se hai una procedura che deve processare mille file e per ognuno di essi lanci una nuova istanza, finirai per strozzare la CPU del server.

Ho lavorato su un sistema di elaborazione log che impiegava sei ore per completare un ciclo perché lanciava un nuovo processo per ogni riga di testo. Riscrivendo la logica per mantenere il lavoro all'interno di una singola sessione persistente o usando i Runspace (che sono molto più leggeri dei Job standard), il tempo di esecuzione è sceso a quindici minuti. La differenza non è stata fatta dall'hardware, ma dalla scelta oculata di come gestire l'invocazione del codice. I Job di PowerShell sono facili da usare, ma hanno un overhead mostruoso. Se hai bisogno di velocità e parallelismo, devi guardare verso i RunspacePool, anche se la curva di apprendimento è più ripida.

💡 Potrebbe interessarti: schema fusibili panda 2

La gestione dei moduli e delle dipendenze condivise

Un errore sottovalutato riguarda il caricamento dei moduli. Se lo script principale carica il modulo ActiveDirectory e poi chiama un secondo script, quest'ultimo avrà accesso a quel modulo? La risposta dipende da come lo chiami. Se usi una nuova sessione, il modulo deve essere ricaricato, perdendo tempo prezioso. Se invece lo script chiamato dipende da una versione specifica di un modulo che differisce da quella del chiamante, entri in quello che chiamiamo l'inferno delle dipendenze.

Nelle infrastrutture critiche, ho imparato che ogni script deve essere autosufficiente ma consapevole. Deve controllare se i moduli necessari sono presenti e, in caso contrario, caricarli con l'opzione -ErrorAction Stop. Non dare mai per scontato che l'ambiente sia pronto. La configurazione dell'ambiente di esecuzione è parte integrante dello script stesso, non un prerequisito da delegare alla fortuna.

Controllo della realtà: cosa serve per non fallire

Smettiamola di raccontarci favole: automatizzare i processi non è un'attività da fare nei ritagli di tempo tra un caffè e l'altro. Se pensi di cavartela con due righe di codice trovate su un forum, prima o poi pagherai il conto. Per padroneggiare la concatenazione di script serve disciplina metodica. Non esiste una formula magica che sostituisca la scrittura di log dettagliati e la gestione maniacale delle eccezioni.

La maggior parte dei fallimenti che ho analizzato negli ultimi dieci anni non derivava da una mancanza di conoscenza dei comandi, ma da una scarsa progettazione dell'architettura. Scrivere codice che gira è facile; scrivere codice che fallisce con grazia, informandoti esattamente di cosa è andato storto, è il vero lavoro. Se non sei disposto a spendere il doppio del tempo nella gestione degli errori rispetto a quella della logica funzionale, allora non sei pronto per gestire sistemi di produzione seri. La stabilità si costruisce sulla sfiducia: devi assumere che ogni file che chiami fallirà, che ogni percorso sarà bloccato e che ogni variabile sarà corrotta. Solo allora il tuo sistema sarà davvero resiliente.

AL

Alessandro Longo

Alessandro Longo unisce competenze editoriali e sensibilità narrativa per spiegare i cambiamenti che incidono sulla vita quotidiana.