Windows Server 2022: “Access is denied” con sc.exe su start/stop servizi — cause, fix e best practice

Dopo la migrazione a Windows Server 2022 potresti vedere “Access is denied” quando usi sc \\server start|stop <servizio> da remoto con operatori non‑amministratori. Il motivo non è la SDDL del servizio: è un controllo di sicurezza aggiuntivo introdotto da Microsoft a partire da Windows 10/Server 1709.

Indice

Scenario e sintomi

In molte infrastrutture, su Windows Server 2016 gli operatori appartenenti a gruppi “di servizio” non amministratori potevano avviare o arrestare specifici servizi in base ai diritti concessi nel descrittore di sicurezza (SDDL). Dopo l’aggiornamento a Windows Server 2022, gli stessi operatori:

  • riescono ancora a eseguire comandi in sola lettura (sc query) sul servizio;
  • ricevono invece errore di accesso negato all’avvio/arresto.
sc \\SRV-APP-01 query Spooler
sc \\SRV-APP-01 start Spooler
[SC] OpenService FAILED 5:
Access is denied.

Il descrittore di sicurezza del servizio (sc sdshow <servizio>) è identico a quello che “prima funzionava”, eppure l’avvio/arresto fallisce.

Motivo tecnico: un controllo aggiuntivo lato SCM

Da Windows 10/Server 1709 Microsoft ha aggiunto un remote access check all’interno del Service Control Manager (SCM, il processo services.exe) che si attiva quando la chiamata arriva da un client remoto. Questo controllo, abilitato per impostazione predefinita ed ereditato integralmente da Windows Server 2022, stabilisce che:

Solo i chiamanti remoti che sono Administrators locali del server possono ottenere i diritti sensibili sui servizi (ad es. SERVICESTART, SERVICESTOP, SERVICECHANGECONFIG e simili).

È importante notare due aspetti:

  1. Il controllo si somma alla valutazione della SDDL del singolo servizio. Anche se la ACL del servizio concede START/STOP al tuo gruppo, la chiamata remota verrà bloccata se l’utente non è amministratore locale.
  2. I diritti “di sola lettura” (per esempio interrogarne lo stato) non sono soggetti al blocco: ecco perché sc query continua a funzionare.

Cosa è cambiato rispetto a Windows Server 2016

La build RTM di Windows Server 2016 non eseguiva questa verifica extra. Perciò, un account remoto che aveva i diritti corretti nella SDDL del servizio poteva invocare StartService/ControlService senza essere amministratore del server. In Server 2022, invece, l’SCM intercetta la richiesta remota e la respinge a monte se il chiamante non è nei local Administrators, indipendentemente dalla SDDL.

Panoramica delle soluzioni

Hai quattro strade praticabili, con un bilanciamento diverso tra sicurezza, impatto operativo e complessità:

OpzioneInterventoQuando usarlaVantaggiSvantaggi
Elenco di eccezione (consigliata)Aggiungi i nomi interni dei servizi a RemoteAccessCheckExemptionList (REGMULTISZ) in HKLM\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM.Vuoi consentire a operatori non‑admin di gestire solo specifici servizi.Controllo puntuale, minimo impatto sul rischio.Richiede gestione dell’elenco; applicazione tipicamente al riavvio.
Disattivazione globale del controlloImposta RemoteAccessExemption (DWORD)=1 in HKLM\SYSTEM\CurrentControlSet\Control.Ambienti isolati o temporaneo ripristino del comportamento legacy.Ripristina il funzionamento su tutti i servizi.Aumenta la superficie d’attacco; scelta da valutare con attenzione.
Aggiungere il gruppo agli Administrators localiIn LUSRMGMT o via GPO, includi il gruppo operativo in Administrators.Quando serve una soluzione immediata e trasversale.Funziona subito, nessuna modifica al registro.Concede privilegi eccessivi, non allineato al principio del minimo privilegio.
Soluzioni alternativeScheduled Task “Run with highest privileges”; PowerShell Remoting con JEA/WinRM; Windows Admin Center con RBAC.Quando preferisci evitare modifiche di sistema e applicare controlli applicativi.Granularità elevata, audit migliorabile.Richiedono progettazione e setup.

Implementazione dettagliata dell’opzione consigliata (eccezione mirata)

Prerequisiti

  • Account con diritti amministrativi sul server di destinazione (il cambio è di configurazione di sistema).
  • Nome interno del servizio (non il Display Name).
  • Finestra di manutenzione per il riavvio del server, qualora necessario.

Passo 1 — Individua il nome interno del servizio

Il “Display Name” può non coincidere con il nome interno. Trovalo con uno dei seguenti metodi:

:: Dal server locale
sc GetKeyName "Print Spooler"

:: Da remoto
sc \SRV-APP-01 GetKeyName "Print Spooler"

:: Oppure in PowerShell
Get-Service | Where-Object DisplayName -like "Print" | Select-Object Name,DisplayName 

Passo 2 — Popola l’elenco di eccezione

Il valore RemoteAccessCheckExemptionList è di tipo REGMULTISZ e contiene una voce per riga con il nome interno dei servizi autorizzati all’avvio/arresto da remoto da parte di chiamanti non‑admin.

Metodo grafico (regedit)

  1. Apri regedit.exe.
  2. Vai a HKEYLOCALMACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM.
  3. Se non esiste, crea il valore RemoteAccessCheckExemptionList di tipo Multi-String.
  4. Inserisci uno per riga i nomi interni dei servizi (es. Spooler, W32Time).

Metodo a riga di comando (PowerShell)

$path = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM'
$services = @('Spooler','W32Time')  # Sostituisci con i tuoi servizi

Crea la chiave se manca

if (-not (Test-Path $path)) { New-Item -Path $path -Force | Out-Null }

Crea o aggiorna il MULTI_SZ

if (-not (Get-ItemProperty -Path $path -Name 'RemoteAccessCheckExemptionList' -ErrorAction SilentlyContinue)) {
New-ItemProperty -Path $path -Name RemoteAccessCheckExemptionList -PropertyType MultiString -Value $services | Out-Null
} else {
$current = (Get-ItemProperty -Path $path -Name RemoteAccessCheckExemptionList).RemoteAccessCheckExemptionList
$new = ($current + $services) | Sort-Object -Unique
Set-ItemProperty -Path $path -Name RemoteAccessCheckExemptionList -Value $new
} 

Metodo a riga di comando (reg.exe)

Per un REGMULTISZ i valori vanno separati con \0 e conclusi da \0\0 (reg.exe aggiunge l’ultimo terminatore automaticamente):

reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM" ^
  /v RemoteAccessCheckExemptionList /t REGMULTISZ ^
  /d "Spooler\0W32Time" /f

Passo 3 — Applica il cambiamento

Il controllo viene effettuato dall’SCM; nella pratica è necessario un riavvio del server per garantire la rilettura coerente del valore. Pianifica una finestra di manutenzione; al rientro, verifica il funzionamento con un account non‑admin.

Passo 4 — Verifica

sc \\SRV-APP-01 start Spooler
sc \\SRV-APP-01 stop Spooler

Controlla anche i log:

  • Event Viewer → Windows Logs → Security con auditing oggetti attivo: eventi 4656/4663 mostrano la richiesta; in caso di blocco vedrai Access Denied.
  • Event Viewer → System: eventi 7036 (service entered the running/stopped state) per confermare l’effetto.
  • Applications and Services Logs → Microsoft‑Windows‑ServiceControlManager/Operational per dettaglio lato SCM.

Disattivazione globale del controllo (non raccomandata)

Se devi ripristinare il comportamento “alla 2016” per tutti i servizi, imposta il DWORD RemoteAccessExemption a 1 in HKLM\SYSTEM\CurrentControlSet\Control.

reg add "HKLM\SYSTEM\CurrentControlSet\Control" /v RemoteAccessExemption /t REG_DWORD /d 1 /f

Questa scelta rimuove la protezione per qualunque servizio e qualunque chiamante remoto con diritti nella SDDL; è quindi da adottare solo in contesti ben isolati, con un attento monitoraggio eventi e un piano di ritorno allo stato sicuro.

Alternativa: mantenere il minimo privilegio senza toccare SCM

Scheduled Task “Run with highest privileges”

Crea un’attività pianificata che esegua Start‑Service/Stop‑Service con account di sistema; gli operatori avviano l’azione chiamando l’attività da remoto.

:: Creazione, una volta per servizio
schtasks /Create /S SRV-APP-01 /RU "SYSTEM" /RL HIGHEST /TN "Ops\Start-Spooler" ^
  /TR "powershell -NoLogo -NoProfile -Command Start-Service -Name Spooler" /SC ONCE /ST 00:00

:: Esecuzione ad-hoc quando serve
schtasks /Run /S SRV-APP-01 /TN "Ops\Start-Spooler" 

Pro: semplice e auditabile; Contro: gestione di più attività e possibili race condition se chiamate in parallelo.

PowerShell Remoting con JEA (Just Enough Administration)

Espone un endpoint WinRM limitato in cui gli operatori possono invocare solo Start-Service/Stop-Service su un set ristretto di nomi, eseguiti da un account RunAs con i privilegi appropriati.

# Esempio semplificato di Role Capability
New-Item -Path 'C:\Program Files\WindowsPowerShell\Modules\Ops.Jea' -ItemType Directory -Force
@'
VisibleCmdlets = @{
    Name = 'Start-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'Spooler','W32Time' }
},
@{ Name = 'Stop-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'Spooler','W32Time' } }
'@ | Set-Content 'C:\Program Files\WindowsPowerShell\Modules\Ops.Jea\Ops.Jea.psrc'

Endpoint JEA
@'
SchemaVersion = '2.0.0.0'
SessionType = 'RestrictedRemoteServer'
RunAsVirtualAccount = $true
RoleDefinitions = @{ 'DOMINIO\GruppoOperativo' = @{ 'RoleCapabilities' = 'Ops.Jea' } }
'@ | Set-Content 'C:\Program Files\WindowsPowerShell\Modules\Ops.Jea\Ops.Jea.pssc'
Register-PSSessionConfiguration -Name 'Ops-Services' -Path 'C:\Program Files\WindowsPowerShell\Modules\Ops.Jea\Ops.Jea.pssc' -Force

Pro: minimo privilegio reale e ottima tracciabilità; Contro: richiede familiarità con JEA e gestione continuativa.

Windows Admin Center con RBAC

Se usi Windows Admin Center, puoi definire ruoli e deleghe per consentire agli operatori l’avvio/arresto di specifici servizi via interfaccia, senza toccare l’SCM. È utile in contesti dove la governance è orientata ai ruoli e l’audit è centrale.

Checklist di diagnostica e sanità del sistema

  • Conferma il contesto remoto: il blocco riguarda chiamate remote. In locale, a parità di SDDL, l’avvio potrebbe riuscire.
  • Verifica la SDDL del servizio: se non concede SERVICESTART/SERVICESTOP al gruppo operativo, il controllo SCM non c’entra. Usa sc sdshow <servizio> e, se necessario, sc sdset con estrema cautela.
  • Controlla l’account: appartiene a Administrators locali (direttamente o per gruppi annidati)? Se sì, il controllo extra non si applica e il problema è altrove.
  • Eventi Security 4656/4663: utili a mostrare Object Access negati/consentiti verso l’oggetto “Service”.
  • Valuta UAC remoto: le restrizioni UAC per account locali (LocalAccountTokenFilterPolicy) possono influire quando usi account locali; con account di dominio amministrativi non è un problema.

Appendice: diritti dei servizi in SDDL (mappa rapida)

Quando analizzi una SDDL di servizio con sc sdshow troverai coppie di lettere che rappresentano diritti specifici. Ecco la mappa più usata:

AbbreviazioneDirittoDescrizione
CCSERVICEQUERYCONFIGLeggere la configurazione del servizio.
DCSERVICECHANGECONFIGModificare la configurazione (account, start type, ecc.).
LCSERVICEQUERYSTATUSLeggere lo stato (running, stopped…).
SWSERVICEENUMERATEDEPENDENTSEnumerare le dipendenze.
RPSERVICE_STARTAvviare il servizio.
WPSERVICE_STOPArrestare il servizio.
DTSERVICEPAUSECONTINUEPausa/continua.
LOSERVICE_INTERROGATEInterrogare il servizio.
CRSERVICEUSERDEFINED_CONTROLInviare comandi personalizzati.
RCREAD_CONTROLLeggere il descrittore di sicurezza.

Questa mappa ti aiuta a verificare che la SDDL sia corretta. Ricorda però: su Windows Server 2022, da remoto l’SCM bloccherà comunque RP/WP/DC e simili se l’utente non è amministratore — a meno di eccezioni configurate.

Domande frequenti (FAQ)

Devo inserire anche i servizi “dipendenti” nella lista di eccezione?

No: l’SCM valuta l’accesso al servizio che apri con OpenService. Se avvii un servizio con dipendenze, queste potrebbero essere avviate automaticamente, ma l’eccezione è richiesta per il servizio che stai gestendo esplicitamente.

Il nome è case‑sensitive?

No, i nomi interni dei servizi non sono case‑sensitive, ma è buona norma mantenerne la forma canonica (Spooler, non spooler).

Posso usare caratteri jolly o gruppi (es. Authenticated Users) in RemoteAccessCheckExemptionList?

No. L’elenco accetta solo nomi interni di servizi; non supporta wildcard né identità di sicurezza. Questo è un vantaggio, perché limita l’eccezione all’oggetto minimo.

Serve un riavvio?

Per coerenza operativa, pianifica un riavvio del server dopo aver modificato l’elenco. L’SCM è un componente di sistema e non è previsto un riavvio “isolato”.

Che differenza c’è tra “local admin” e “domain admin”?

Il controllo verifica l’appartenenza al gruppo Administrators del server di destinazione. I Domain Admins sono amministratori locali per impostazione predefinita, a meno di policy personalizzate; gruppi di dominio personalizzati lo diventano solo se li aggiungi agli Administrators locali o via GPO.

“net start/stop” cambia qualcosa rispetto a “sc”?

No. Anche “net start/stop” invoca l’SCM; le regole sono le stesse. “sc.exe” fornisce messaggi e diagnostica migliori.

Se disattivo globalmente il controllo, rischio di più?

Sì. Riapri la possibilità che un utente remoto non‑admin con diritti nella SDDL avvii/stoppi servizi (anche critici). Meglio preferire l’elenco di eccezione e la delega mirata.

Best practice operative

  • Principio del minimo privilegio: abilita il controllo extra per impostazione predefinita; riduci le eccezioni al minimo indispensabile.
  • Lista di eccezioni “pulita”: niente wildcard, niente nomi superflui; rimuovi periodicamente le voci non più necessarie.
  • Test in laboratorio: valida la configurazione su server di staging prima di distribuire in produzione.
  • Audit continuo: monitora gli eventi di avvio/arresto nel SIEM; in caso di disattivazione globale, aumenta la sorveglianza.
  • Documentazione e change record: ogni eccezione deve essere tracciata con motivazione, data di scadenza e owner.
  • Automazione sicura: se lavori su decine di server, usa script PowerShell con idempotenza (aggiunge solo ciò che manca) e logging.

Esempio completo: dal problema alla soluzione

  1. Rilevazione: gli operatori help‑desk non riescono più ad avviare Spooler su SRV‑PRINT‑02; sc query funziona, sc start no.
  2. Ipotesi: migrazione recente a Server 2022 ⇒ probabile blocco SCM per chiamanti remoti non‑admin.
  3. Verifica: il gruppo “HelpDesk‑Print” è presente nella SDDL del servizio con diritti START/STOP; eventi Security mostrano richiesta da rete. Nessun membro è amministratore locale.
  4. Decisione: applicare eccezione mirata, senza elevare il gruppo.
  5. Implementazione: aggiunto Spooler a RemoteAccessCheckExemptionList via script PowerShell centralizzato su SRV‑PRINT‑02.
  6. Approvazione e change: change record con motivazione (operatività stampe), owner (IT Ops), scadenza (riesame trimestrale).
  7. Convalida: dopo riavvio, sc \\SRV-PRINT-02 start Spooler eseguito con account help‑desk ha esito positivo; eventi 7036 confermano.
  8. Monitoraggio: dashboard SIEM su eventi 7036 e su chiamate fallite/riuscite da host remoti.

Script di distribuzione (multi‑server)

Esempio di distribuzione su più host con idempotenza e report finale:

$servers = @('SRV-APP-01','SRV-PRINT-02','SRV-SQL-01')
$svcList = @('Spooler','W32Time')  # per ciascun server adatta la lista se necessario

$results = foreach ($s in $servers) {
Invoke-Command -ComputerName $s -ScriptBlock {
param($svcList)
$path = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM'
if (-not (Test-Path $path)) { New-Item -Path $path -Force | Out-Null }
$name = 'RemoteAccessCheckExemptionList'
$before = @()
if ($p = Get-ItemProperty -Path $path -Name $name -ErrorAction SilentlyContinue) {
$before = @($p.$name)
}
$after = ($before + $svcList) | Sort-Object -Unique
if ($before -ne $after) {
if ($before.Count -eq 0) {
New-ItemProperty -Path $path -Name $name -PropertyType MultiString -Value $after | Out-Null
} else {
Set-ItemProperty -Path $path -Name $name -Value $after
}
[PSCustomObject]@{ Server = $env:COMPUTERNAME; Status = 'Updated'; Values = ($after -join ', ') }
} else {
[PSCustomObject]@{ Server = $env:COMPUTERNAME; Status = 'NoChange'; Values = ($before -join ', ') }
}
} -ArgumentList ($svcList) -ErrorAction Stop
}
$results | Format-Table -AutoSize 

Linee guida per la sicurezza

  • Dov’è la superficie d’attacco? Esporre l’avvio/arresto da remoto può interrompere servizi critici (DB, code, antivirus). Mantieni l’elenco lean e rivisitalo con cadenza periodica.
  • Segregazione dei ruoli: separa gli operatori che possono avviare/fermare servizi dai team che possono modificarne la configurazione (change config).
  • Logging e alerting: crea alert su arresti/avvii fuori orario e su tentativi falliti ripetuti da same IP/same user.
  • Backup della configurazione: esporta regole e chiavi di registro prima di ogni modifica per garantire rollback rapido.

Conclusione

Il comportamento osservato su Windows Server 2022 è “by design”: un controllo di sicurezza lato SCM blocca avvio/arresto da remoto per gli utenti che non sono amministratori locali, a prescindere dalla SDDL del singolo servizio. La soluzione raccomandata è creare un elenco di eccezione mirato, limitato ai soli servizi operativi che gli operatori devono gestire. In alternativa, valuta JEA/WinRM o attività pianificate per mantenere il principio del minimo privilegio. Evita la disattivazione globale del controllo se non in casi eccezionali e con copertura di monitoraggio adeguata.


Riferimenti operativi rapidi

  • Chiave elenco eccezioni: HKLM\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM\RemoteAccessCheckExemptionList (REGMULTISZ, nomi interni servizi).
  • Toggle globale: HKLM\SYSTEM\CurrentControlSet\Control\RemoteAccessExemption (DWORD, 1=disabilita controllo extra).
  • Comandi utili: sc GetKeyName, sc sdshow, Get‑Service, wevtutil.
  • Eventi da monitorare: Security 4656/4663, System 7036, SCM Operational (varie ID).

Implementando l’opzione 1 (eccezione mirata) ripristini l’uso di sc start/stop per operatori non‑admin su Windows Server 2022 mantenendo un profilo di rischio molto simile a Windows Server 2016, ma con un controllo aggiuntivo centralizzato e gestibile.


Nota: se stai investigando un singolo servizio, verifica anche che il suo StartType non sia disabilitato (sc qc <servizio>START_TYPE) e che l’account di esecuzione del servizio non imponga vincoli che impediscano l’arresto (ad es. dipendenze rigide o policy di protezione del fornitore).

Indice