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.
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:
- 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.
- 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à:
Opzione | Intervento | Quando usarla | Vantaggi | Svantaggi |
---|---|---|---|---|
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 controllo | Imposta 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 locali | In 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 alternative | Scheduled 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)
- Apri
regedit.exe
. - Vai a
HKEYLOCALMACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM
. - Se non esiste, crea il valore
RemoteAccessCheckExemptionList
di tipo Multi-String. - 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. Usasc 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:
Abbreviazione | Diritto | Descrizione |
---|---|---|
CC | SERVICEQUERYCONFIG | Leggere la configurazione del servizio. |
DC | SERVICECHANGECONFIG | Modificare la configurazione (account, start type, ecc.). |
LC | SERVICEQUERYSTATUS | Leggere lo stato (running, stopped…). |
SW | SERVICEENUMERATEDEPENDENTS | Enumerare le dipendenze. |
RP | SERVICE_START | Avviare il servizio. |
WP | SERVICE_STOP | Arrestare il servizio. |
DT | SERVICEPAUSECONTINUE | Pausa/continua. |
LO | SERVICE_INTERROGATE | Interrogare il servizio. |
CR | SERVICEUSERDEFINED_CONTROL | Inviare comandi personalizzati. |
RC | READ_CONTROL | Leggere 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
- Rilevazione: gli operatori help‑desk non riescono più ad avviare
Spooler
su SRV‑PRINT‑02;sc query
funziona,sc start
no. - Ipotesi: migrazione recente a Server 2022 ⇒ probabile blocco SCM per chiamanti remoti non‑admin.
- Verifica: il gruppo “HelpDesk‑Print” è presente nella SDDL del servizio con diritti START/STOP; eventi Security mostrano richiesta da rete. Nessun membro è amministratore locale.
- Decisione: applicare eccezione mirata, senza elevare il gruppo.
- Implementazione: aggiunto
Spooler
aRemoteAccessCheckExemptionList
via script PowerShell centralizzato su SRV‑PRINT‑02. - Approvazione e change: change record con motivazione (operatività stampe), owner (IT Ops), scadenza (riesame trimestrale).
- Convalida: dopo riavvio,
sc \\SRV-PRINT-02 start Spooler
eseguito con account help‑desk ha esito positivo; eventi 7036 confermano. - 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).