Si apre il terminale, parte PowerShell e dopo un istante il processo termina con un errore. Nessun prompt, nessuna possibilità di digitare un comando.
La causa non è il profilo utente né un modulo installato, ma il banner con cui PowerShell 7 avvisa che è disponibile una nuova versione. Vediamo come riconoscere l’errore, perché si verifica, come risolverlo con una variabile d’ambiente e come tornare alla configurazione normale quando il difetto sarà corretto.
Il sintomo: Process terminated e totalWidth negativo
All’avvio di PowerShell 7 compare l’intestazione con la versione e subito dopo il processo viene terminato
PowerShell 7.6.7
Process terminated.
totalWidth ('-5') must be a non-negative value. (Parameter 'totalWidth')
Actual value was -5.
at System.Environment.FailFast(...)
System.ArgumentOutOfRangeException: totalWidth ('-5') must be a non-negative value. (Parameter 'totalWidth')
at System.String.PadRight(Int32 totalWidth, Char paddingChar)
at Microsoft.PowerShell.UpdatesNotification.ShowUpdateNotification(PSHostUserInterface hostUI)
at Microsoft.PowerShell.ConsoleHost.Start(String bannerText, String helpText, Boolean issProvidedExternally)
[processo terminato con codice 2148734499 (0x80131623)]Gli elementi che identificano questo specifico problema sono tre:
- il messaggio “totalWidth (‘-5’) must be a non-negative value”, dove il numero negativo può cambiare
- la riga “Microsoft.PowerShell.UpdatesNotification.ShowUpdateNotification” nello stack, che indica il punto in cui il codice si interrompe
- il codice di uscita “0x80131623”, che corrisponde a una terminazione forzata del runtime .NET: il processo viene chiuso senza alcun tentativo di recupero
Perché succede: il banner degli aggiornamenti
PowerShell 7 controlla in background, circa una volta al giorno, se è stata pubblicata una versione più recente di quella installata. Quando ne trova una, all’avvio successivo mostra un riquadro che invita ad aggiornare. Questo spiega perché il problema compare dal nulla: basta che Microsoft pubblichi una nuova release perché, dal giorno dopo, ogni avvio provi a disegnare il banner.
Per allineare il testo dentro il riquadro, PowerShell usa il metodo PadRight, che aggiunge spazi fino a raggiungere una certa larghezza. Questa larghezza viene calcolata a partire da quella della console. Se la console viene rilevata troppo stretta, il calcolo produce un numero negativo, PadRight lancia un’eccezione e, poiché l’errore avviene durante l’avvio dell’host, il processo viene terminato con FailFast.
La soluzione: disattivare il controllo con POWERSHELL_UPDATECHECK
Il comportamento del controllo degli aggiornamenti è governato dalla variabile d’ambiente POWERSHELL_UPDATECHECK che accetta tre valori:
- Default: notifica le nuove versioni del proprio canale (comportamento predefinito)
- LTS: notifica solo le nuove versioni LTS
- Off: disattiva il controllo e quindi il banner
Impostando Off il banner non viene più disegnato e il codice che va in errore non viene eseguito.
Poiché PowerShell si chiude all’avvio, il comando va eseguito da una shell che funziona: il Prompt dei comandi (cmd.exe) oppure Windows PowerShell 5.1 (powershell.exe), che è un programma separato da PowerShell 7 e non ha questo banner.
Il comando setx salva la variabile nel profilo dell’utente corrente, in modo permanente
setx POWERSHELL_UPDATECHECK Offsetx scrive la variabile nel registro, ma non la comunica ai processi già in esecuzione. Ogni programma riceve le variabili d’ambiente al momento dell’avvio, copiandole dal processo che lo lancia. VS Code le ha lette quando è stato aperto, e i terminali che crea le ereditano da lui. Aprire un nuovo pannello terminale non basta, perché riceverà ancora l’ambiente vecchio.
Per rendere effettiva la modifica:
- chiudere tutte le finestre di VS Code, non solo quella in uso
- chiudere ogni altro terminale aperto, compresi quelli rimasti nello stato di errore
- eseguire il comando setx
- riaprire VS Code o il terminale
Da una nuova finestra del Prompt dei comandi, aperta dopo setx, controlliamo il valore
$env:POWERSHELL_UPDATECHECKL’output atteso è Off.
Aggiornare PowerShell
Il controllo degli aggiornamenti è utile: senza il banner non ci si accorge delle nuove versioni, comprese quelle con correzioni di sicurezza. Quando sarà disponibile una release che corregge il difetto conviene quindi aggiornare e riattivarlo
winget upgrade Microsoft.PowerShellDopo l’aggiornamento rimuoviamo la variabile dall’ambiente dell’utente. Impostarla a stringa vuota non basta, ma va eliminata. Questo comando lo fa sia da PowerShell 7 sia da Windows PowerShell 5.1
[Environment]::SetEnvironmentVariable("POWERSHELL_UPDATECHECK", $null, "User")