PowerShell che si chiude subito su Windows Server: errore “Starting the CLR failed” con Access Denied

Su alcune installazioni di Windows Server 2019 può capitare che la console di Windows PowerShell 5.1 si apra per un istante e si chiuda subito. Da CMD compare “Starting the CLR failed with HRESULT 0x80070005” (ACCESS_DENIED). Qui trovi una procedura concreta per isolare la causa e ripristinare l’ambiente.

Indice

Scenario e sintomi

  • Ambiente con server fisici Windows Server 2019 Datacenter (build 17763.5576).
  • Avvio della console di Windows PowerShell 5.1: finestra che lampeggia e si chiude all’istante.
  • Esecuzione da cmd.exe: messaggio “Starting the CLR failed with HRESULT 0x80070005” (ACCESS_DENIED).
  • Nessun evento registrato nei log di Sistema o Applicazione all’istante del crash.
  • DISM/SFC riportano “riparazione completata”, ma il problema persiste.
  • La funzionalità Windows PowerShell non risulta disinstallabile da Server Manager.

Come interpretare l’errore

Windows PowerShell 5.1 è un host .NET Framework: all’avvio, powershell.exe carica il Common Language Runtime (CLR) di .NET Framework tramite lo stub mscoree.dll. Il codice 0x80070005 è l’equivalente di ACCESS_DENIED. In questo contesto significa che il processo non riesce a inizializzare il CLR perché qualcosa ne impedisce il caricamento o l’accesso a file/registro necessari (per esempio ACL corrotti su cartelle o DLL del runtime, chiavi di registro danneggiate, blocco da parte di AV/EDR, criteri di controllo applicazioni).

Soluzione rapida consigliata

Se devi ripristinare operatività nel minor tempo possibile, applica prima la correzione più efficace e poi metti in sicurezza il futuro dell’ambiente.

PassoAzione propostaPerché funziona
1Reinstallare o riparare .NET Framework 4.8 Runtime (rimuovere eventuali 4.x presenti quando possibile, riavviare, quindi installare o lanciare un Repair dal pacchetto ufficiale).PowerShell 5.1 dipende dal CLR di .NET Framework. L’errore 0x80070005 indicizza spesso componenti CLR danneggiati o con ACL errati. La riparazione ripristina binari, chiavi di registro e permessi predefiniti.
2Usare PowerShell 7 come workaround o sostituzione stabile: winget install --id Microsoft.PowerShell oppure MSI offline.PowerShell 7 (pwsh.exe) gira su .NET moderno e non dipende dal CLR di .NET Framework; continua a funzionare anche se la 5.1 è compromessa.

Procedura dettagliata

Preparazione

  • Pianifica una finestra di manutenzione e un riavvio.
  • Assicurati di avere privilegi amministrativi locali.
  • Metti in pausa temporaneamente policy di hardening estreme o protezioni AV/EDR che impediscano operazioni su cartelle di sistema (documenta la modifica e riabilita a fine attività).
  • Prepara una cartella di lavoro, ad es. C:\Temp.

Riparare o reinstallare .NET Framework 4.8

Su Windows Server 2019 la linea 4.x è generalmente installata come aggiornamento. A seconda della baseline, l’opzione Disinstalla potrebbe non essere disponibile; in quel caso usa il Repair del pacchetto 4.8.

Metodo grafico

  1. Apri appwiz.cplProgrammi e funzionalitàVisualizza aggiornamenti installati.
  2. Individua le voci .NET Framework 4.x o gli aggiornamenti cumulativi correlati; se disinstallabili, rimuovi nell’ordine consigliato dal vendor.
  3. Riavvia il server.
  4. Esegui il setup di .NET Framework 4.8 e scegli Ripara o Installa.

Metodo da riga di comando

Copia il pacchetto di installazione nella cartella di lavoro e lancia:

rem Esegui come Administrator da CMD
C:\Temp\ndp48-x86-x64-allos-*.exe /repair /quiet /norestart /log C:\Temp\ndp48-repair.log

Se la disinstallazione è consentita:

rem Disinstalla eventuale 4.x
C:\Temp\ndp48-x86-x64-allos-*.exe /uninstall /quiet /norestart /log C:\Temp\ndp48-uninst.log

rem Riavvia e poi installa 4.8
C:\Temp\ndp48-x86-x64-allos-*.exe /install /quiet /norestart /log C:\Temp\ndp48-install.log 

Verifica immediata

Dopo il riavvio, da cmd.exe lancia:

powershell -NoProfile -NoLogo -Command "$PSVersionTable"

Se la 5.1 si apre normalmente, il problema è risolto. In caso contrario, prosegui.

Installare PowerShell 7

Adotta PowerShell 7 per ripristinare operatività e ridurre il rischio di ricadute. Rimane affiancato a 5.1 senza sovrascriverla.

Installazione con winget

Se l’host supporta il gestore pacchetti:

winget install --id Microsoft.PowerShell --source winget --accept-package-agreements --accept-source-agreements

Nota: su alcune build di Server 2019 winget non è presente di default; in tal caso usa l’MSI offline.

Installazione tramite MSI offline

  1. Trasferisci il pacchetto MSI di PowerShell 7 nella cartella di lavoro.
  2. Installa in modalità silenziosa:
msiexec /i C:\Temp\PowerShell-7.x.x-win-x64.msi ADDEXPLORERCONTEXTMENUOPENPOWERSHELL=1 ENABLEPSREMOTING=1 USEMU=1 /qn /norestart /l*v C:\Temp\pwsh-msi.log

Verifica:

"C:\Program Files\PowerShell\7\pwsh.exe" -NoLogo -Command "$PSVersionTable"

Controlli rapidi dopo la correzione

  • Avvio 5.1: powershell -NoProfile deve restare aperto e rispondere.
  • Modulo base: Get-Process | Select-Object -First 3 deve produrre output.
  • PS7: pwsh -NoLogo deve avviarsi e mostrare la versione.
  • Event Viewer: verifica assenza di errori “.NET Runtime” e “Application Error” in corrispondenza dell’avvio.

Azioni facoltative ma utili

  • Avvio senza profilo: powershell -NoProfile per escludere profili utente corrotti.
  • Avvio elevato: esegui come Administrator per isolare problemi di token/permessi.
  • Verifica ACL su cartelle critiche: icacls C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /t /c icacls C:\Windows\System32\WindowsPowerShell\v1.0 /t /c Se noti errori “Access is denied” o eredità spezzata, valuta un ripristino degli ACL predefiniti (con estrema cautela e change approvato): icacls C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /reset /t /c icacls C:\Windows\System32\WindowsPowerShell\v1.0 /reset /t /c
  • DISM con sorgente in caso di component store incoerente: DISM /Online /Cleanup-Image /RestoreHealth /Source:X:\sources\install.wim /LimitAccess sfc /scannow Usa un’ISO della stessa build per migliorare la qualità della riparazione.
  • Software di sicurezza: sospendi temporaneamente protezioni che potrebbero bloccare il caricamento del CLR. Riabilita e crea le opportune esclusioni dopo i test.

Diagnostica avanzata

Se il comportamento persiste, puoi raccogliere indizi più profondi per capire dove avviene l’ACCESS_DENIED.

Dump locali di WER

Abilita dump del processo powershell.exe per analizzare lo stop:

reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\powershell.exe" /v DumpType /t REG_DWORD /d 2 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\powershell.exe" /v DumpFolder /t REGEXPANDSZ /d "C:\Dumps" /f
mkdir C:\Dumps

Riproduci il crash, poi esamina i dump con gli strumenti adeguati (ricorda di disattivare i dump al termine).

Log di binding delle assembly (.NET Framework Fusion)

Attiva temporaneamente i log di Fusion per individuare errori di caricamento:

reg add "HKLM\SOFTWARE\Microsoft\Fusion" /v EnableLog /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Microsoft\Fusion" /v ForceLog  /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Microsoft\Fusion" /v LogFailures /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Microsoft\Fusion" /v LogResourceBinds /t REG_DWORD /d 1 /f

Dopo i test, ripristina i valori per evitare overhead.

Controllo criteri di controllo applicazioni

Valuta la presenza di AppLocker o Windows Defender Application Control (WDAC). Eventuali blocchi possono non comparire nei log classici. Apri i registri in Applications and Services Logs → Microsoft → Windows → AppLocker e in CodeIntegrity per rilevare policy troppo restrittive.

Registro e componenti critici

Le aree più sensibili per l’errore in oggetto sono:

  • HKLM\SOFTWARE\Microsoft\.NETFramework e HKLM\SOFTWARE\WOW6432Node\Microsoft\.NETFramework
  • %windir%\Microsoft.NET\Framework64\v4.0.30319 e %windir%\System32 (file come clr.dll, mscoree.dll)
  • %windir%\System32\WindowsPowerShell\v1.0

Permessi disallineati, eredità interrotta o file in quarantena possono causare la chiusura immediata dell’host.

Ripristino di PowerShell 5.1 e limiti

Windows PowerShell 5.1 è una componente del sistema. Non è redistribuibile come feature autonoma e non esiste un “setup” separato supportato. Se il componente è irrecuperabile, l’unica strada davvero garantita resta un repair‑install (in‑place upgrade) con un’ISO della stessa edizione/lingua/build, conservando dati e ruoli. Valuta attentamente tempi e impatto sul servizio.

Approccio a scala su più server

Se il fenomeno interessa più host (ad esempio quattordici nodi fisici) è probabile una causa comune: immagine di base, GPO, hardening, EDR. Ecco come procedere in sicurezza:

  1. Segmenta: scegli un solo server come “canarino” per applicare la procedura e validare i passi.
  2. Confronta con un server sano: usa gpresult /H C:\Temp\gpo.html su entrambi per confrontare GPO applicate.
  3. Automatizza la distribuzione dell’MSI di PowerShell 7 con strumenti di gestione già in uso (Configuration Manager, strumenti di orchestrazione o attività pianificate): schtasks /Create /TN "Install-PowerShell7" /SC ONCE /ST 23:00 /RU "SYSTEM" ^ /TR "msiexec /i C:\Temp\PowerShell-7.x.x-win-x64.msi /qn /norestart /l*v C:\Temp\pwsh-msi.log" schtasks /Run /TN "Install-PowerShell7"
  4. Verifica remoto: dopo l’installazione, usa pwsh.exe per eseguire comandi di check (dove disponibile), oppure strumenti di inventario per leggere le versioni installate.

Tabella decisionale rapida

SintomoPossibile causaControlloRimedio
Finestra si chiude subitoCLR non inizializzatoErrore Starting the CLR failed 0x80070005 da CMDRepair o reinstall di .NET Framework 4.8
Nessun log in Applicazione/SistemaCrash prima del loggerAbilita WER LocalDumpsAnalizza dump, verifica file/ACL
Funzionalità non disinstallabileComponente di sistemaServer ManagerUsa repair‑install se irriparabile
Funziona solo come AdministratorACL su file/registroicacls su cartelle .NET e PowerShellRipristina ACL predefiniti
Solo alcuni server colpitiGPO/EDR/hardeningConfronto gpresult, log AppLocker/WDACAllinea policy, crea esclusioni

Verifiche funzionali dopo il fix

  1. Moduli di sistema: powershell -NoProfile -Command "Get-Module Microsoft.PowerShell.Management -ListAvailable | Select-Object Name,Version"
  2. Esecuzione script di test: powershell -NoProfile -File C:\Temp\hello.ps1 con contenuto minimo: Write-Host "OK: $($PSVersionTable.PSVersion)"
  3. Compatibilità PS7: valida script e moduli business‑critical su pwsh. Dove necessario, usa il parametro -UseWindowsPowerShell su cmdlet compatibili o valuta l’aggiornamento dei moduli.

Domande frequenti

Posso “reinstallare” solo PowerShell 5.1?
No: è parte del sistema operativo. Le strade supportate sono la riparazione di .NET Framework, la correzione dei permessi e, se tutto fallisce, un repair‑install di Windows Server.

Perché DISM/SFC dicono che è tutto a posto?
Perché il component store e i binari di sistema possono risultare coerenti anche se permessi ereditati, chiavi di registro o hook di sicurezza bloccano il CLR all’avvio.

PowerShell 7 sostituisce 5.1?
No: convivono. powershell.exe resta 5.1, pwsh.exe è 7.x. Puoi impostare PS7 come shell predefinita dove appropriato, mantenendo 5.1 per componenti legacy quando sarà di nuovo funzionante.

Winget non c’è, come faccio?
Usa l’MSI di PowerShell 7 e procedi con msiexec. È la via più semplice su server senza App Installer.

Script di utilità

Un batch di verifica minima da eseguire dopo la riparazione:

@echo off
setlocal
echo [1] Test avvio PowerShell 5.1
powershell -NoProfile -Command "$PSVersionTable" || echo ERRORE: avvio 5.1 non riuscito

echo [2] Test moduli base
powershell -NoProfile -Command "Get-Command Get-Process" || echo ERRORE: moduli non disponibili

echo [3] Test PowerShell 7
if exist "C:\Program Files\PowerShell\7\pwsh.exe" (
"C:\Program Files\PowerShell\7\pwsh.exe" -NoLogo -Command "$PSVersionTable"
) else (
echo PowerShell 7 non installato
)
endlocal 

Buone pratiche per evitare ricadute

  • Baseline immutabile: assicurati che l’immagine di riferimento non contenga personalizzazioni delle ACL in %windir%\Microsoft.NET e %windir%\System32\WindowsPowerShell.
  • Esclusioni AV/EDR: prevedi esclusioni mirate per il runtime .NET e per powershell.exe/pwsh.exe quando necessario e approvato.
  • Monitoraggio: implementa una probe che esegua powershell -NoProfile -Command "$PSVersionTable" ogni giorno e segnali anomalie.
  • Documentazione: registra i passaggi effettuati (log di setup, versioni, orari) per correlare eventi futuri.

Conclusioni operative

L’errore “Starting the CLR failed with HRESULT 0x80070005” è un sintomo di un problema nel sottosistema .NET Framework, spesso legato a permessi o componenti corrotti. Nella maggioranza dei casi la combinazione riparazione/reinstallazione di .NET Framework 4.8 e l’adozione di PowerShell 7 come shell di lavoro ripristina tempestivamente l’operatività senza interventi invasivi. Se la 5.1 resta inutilizzabile e le policy aziendali lo consentono, il repair‑install del sistema è il metodo supportato per riportare il componente allo stato originale.


Checklist sintetica

  • Esegui come Administrator e prova -NoProfile.
  • Ripara o reinstalla .NET Framework 4.8; riavvia.
  • Installa PowerShell 7 per continuità operativa.
  • Controlla ACL e policy AppLocker/WDAC se l’errore persiste.
  • In ultima istanza, pianifica un repair‑install di Windows Server.

Nota: Valuta ogni comando in base alle tue policy di change management. Esegui sempre un backup e opera in finestre di manutenzione pianificate.

Indice