Qué vas a conseguir
Sacar los servicios y las tareas programadas de las cuentas svc- con una contraseña que alguien apuntó en una hoja hace años, y pasarlos a cuentas de servicio administradas de grupo (gMSA): Active Directory genera y cambia la contraseña solo, y solo los servidores autorizados pueden usarla. Y, mientras quede alguna cuenta antigua, resolver en diez minutos el ticket del servicio que no arranca porque alguien le cambió la contraseña.
Antes de empezar
- Un dominio con controladores de dominio Windows Server 2012 o posterior (cualquier versión con soporte lo cumple).
- Permisos para crear objetos en
OU=Cuentas de servicio,DC=contoso,DC=localy, una vez por bosque, alguien de Administradores de empresa o Administradores del dominio para la clave KDS. - En cada servidor que use la gMSA, el módulo de AD:
Install-WindowsFeature RSAT-AD-PowerShell. - El inventario de lo que corre con cuentas de dominio. Empieza por aquí:
Get-CimInstance Win32_Service | Where-Object StartName -like 'CONTOSO\*' | Select-Object Name, StartName, State, StartModeName StartName State StartMode---- --------- ----- ---------ContosoFacturas CONTOSO\svc-facturas Running AutoGet-ScheduledTask | Where-Object { $_.Principal.UserId -like '*svc-*' } | Select-Object TaskPath, TaskName, @{n='Cuenta';e={$_.Principal.UserId}}TaskPath TaskName Cuenta-------- -------- ------\Contoso\ Exportar facturas CONTOSO\svc-facturas1. Qué cuenta usar
| Cuenta | Dónde vale | Contraseña | Cuándo |
|---|---|---|---|
Cuenta virtual (NT SERVICE\Servicio) | Solo en ese servidor; en la red, como la cuenta del equipo | Ninguna | El servicio no necesita entrar en otros servidores |
Cuenta de usuario del dominio (svc-) | Cualquier servidor | La pones y la cambias tú | Solo si la aplicación no admite otra cosa |
gMSA (gmsa-informes$) | Los servidores del grupo autorizado | AD la genera (240 caracteres) y la cambia cada 30 días | Un servicio, una tarea o un grupo de IIS que entra en SQL Server, un recurso compartido o AD |
Una gMSA por aplicación, no una para todo: si alguien la usa mal, el alcance es una aplicación.
2. La clave raíz KDS (una vez por bosque)
Los controladores de dominio calculan las contraseñas de las gMSA a partir de una clave raíz KDS. Comprueba si ya existe:
Get-KdsRootKeyAdd-KdsRootKey -EffectiveImmediatelyGuid----4e1b5c3a-8d2f-4b6e-9a71-0c3d5e7f9b12- Con
-EffectiveImmediately, la clave no se puede usar hasta 10 horas después: es el margen para que replique a todos los controladores. Créala la víspera. - En un laboratorio con un solo controlador se salta la espera con
Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10)). En producción, no.
3. Crear la gMSA
Primero un grupo con los servidores que podrán usarla; después la cuenta:
New-ADGroup -Name 'GG-gMSA-Informes' -GroupScope Global -Path 'OU=Cuentas de servicio,DC=contoso,DC=local'Add-ADGroupMember -Identity 'GG-gMSA-Informes' -Members 'SRV-GESTION01$'New-ADServiceAccount -Name 'gmsa-informes' -DNSHostName 'gmsa-informes.contoso.local' -PrincipalsAllowedToRetrieveManagedPassword 'GG-gMSA-Informes' -Path 'OU=Cuentas de servicio,DC=contoso,DC=local'Get-ADServiceAccount gmsa-informes -Properties PrincipalsAllowedToRetrieveManagedPassword, ManagedPasswordIntervalInDays | Select-Object Name, ManagedPasswordIntervalInDays, PrincipalsAllowedToRetrieveManagedPasswordName ManagedPasswordIntervalInDays PrincipalsAllowedToRetrieveManagedPassword---- ----------------------------- ------------------------------------------gmsa-informes 30 {CN=GG-gMSA-Informes,OU=Cuentas de servicio,DC=contoso,DC=local}- El nombre tiene un máximo de 15 caracteres: es el
sAMAccountName, al que AD añade el$. - Un servidor que acabas de añadir al grupo no lo sabe hasta que renueva su ticket de Kerberos: reinícialo o, sin reiniciar,
klist -li 0x3e7 purgeen ese servidor.
4. Instalar y probar en el servidor
Install-ADServiceAccount gmsa-informesTest-ADServiceAccount gmsa-informesTrueTrue significa que este servidor puede pedir la contraseña a AD. False casi siempre es uno de tres: el servidor no está en el grupo, no ha renovado su ticket desde que lo añadiste o la clave KDS todavía no es efectiva.
5. Asignarla a un servicio
En services.msc, el servicio › Propiedades › Iniciar sesión:
Desde la línea de comandos, en una consola cmd (en Windows PowerShell 5.1 las comillas vacías no llegan a sc.exe):
sc.exe config ContosoInformes obj= "CONTOSO\gmsa-informes$" password= ""[SC] ChangeServiceConfig CORRECTOsc.exe stop ContosoInformes && sc.exe start ContosoInformessc.exeno concede el derecho Iniciar sesión como servicio: si lo usas, dalo por GPO en Asignación de derechos de usuario o el servicio no arrancará (evento 7041).- Después, los permisos que la aplicación necesita, a la gMSA y nada más: su base de datos en SQL Server (
CREATE LOGIN [CONTOSO\gmsa-informes$] FROM WINDOWS), su carpeta compartida, su OU.
6. Asignarla a una tarea programada
La interfaz del Programador de tareas pide una contraseña y no sirve para una gMSA. Con PowerShell:
$quien = New-ScheduledTaskPrincipal -UserId 'CONTOSO\gmsa-informes$' -LogonType PasswordSet-ScheduledTask -TaskName 'Exportar informes' -TaskPath '\Contoso\' -Principal $quien(Get-ScheduledTask -TaskName 'Exportar informes' -TaskPath '\Contoso\').Principal | Select-Object UserId, LogonTypeUserId LogonType------ ---------gmsa-informes$ PasswordLa gMSA necesita el derecho Iniciar sesión como proceso por lotes en el servidor. Un ejemplo completo de tarea con gMSA, con el script y sus comprobaciones, está en el informe semanal de Active Directory con PowerShell.
7. El ticket: "el servicio no arranca después del cambio de contraseña"
Lunes, 7:50. La aplicación de facturación no responde. En srv-app02, el servicio ContosoFacturas está detenido y al arrancarlo: Error 1069: El servicio no se inició debido a un error de inicio de sesión.
Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='Service Control Manager'; Id=7000,7038,7041; StartTime=(Get-Date).AddDays(-3)} | Select-Object TimeCreated, Id, Message -First 2 | Format-ListTimeCreated : 03/11/2026 7:52:10Id : 7038Message : El servicio ContosoFacturas no pudo iniciar sesión como CONTOSO\svc-facturas con la contraseña configurada actualmente debido al siguiente error: El nombre de usuario o la contraseña no son correctos.TimeCreated : 03/11/2026 7:52:10Id : 7000Message : El servicio ContosoFacturas no pudo iniciarse debido al siguiente error: El servicio no se ha iniciado debido a un error de inicio de sesión.- 7038 + 7000: la contraseña guardada en el servicio ya no es la de AD.
- 7041: la contraseña es buena, pero a la cuenta le falta el derecho Iniciar sesión como servicio (una GPO de seguridad lo ha sobrescrito).
Después, la cuenta en AD:
Get-ADUser svc-facturas -Properties PasswordLastSet, LockedOut, Enabled, AccountExpirationDate | Select-Object Enabled, LockedOut, PasswordLastSet, AccountExpirationDateEnabled LockedOut PasswordLastSet AccountExpirationDate------- --------- --------------- --------------------- True True 31/10/2026 18:04:33La contraseña se cambió el viernes (PasswordLastSet) y la cuenta está bloqueada: el servicio, y probablemente otros servidores con la misma cuenta, siguen probando la contraseña vieja. Por eso el inventario del principio importa: hay que cambiarla en todos los sitios donde se usa, o la cuenta se vuelve a bloquear en minutos.
- La contraseña nueva, del gestor de contraseñas del equipo (o la pide el responsable de la aplicación).
- En cada servidor y en cada tarea que usa
svc-facturas: Propiedades › Iniciar sesión con la contraseña nueva (osc.exe config ContosoFacturas obj= "CONTOSO\svc-facturas" password= "..."desde cmd). Unlock-ADAccount svc-facturasyStart-Service ContosoFacturas. Comprueba que la aplicación responde y que no hay nuevos 7038.- El arreglo de verdad, en un cambio planificado: una gMSA
gmsa-facturascon los puntos 3 a 6, permisos en SQL Server y la cuentasvc-facturasdeshabilitada tras dos semanas sin uso.
Si el servicio ya corría con una gMSA y da 7000, la causa es otra: Test-ADServiceAccount en ese servidor. Casi siempre es un servidor nuevo o reinstalado que nadie añadió al grupo GG-gMSA-....
En el ticket: servicio, eventos, estado de la cuenta, dónde se cambió la contraseña y la propuesta de pasar a gMSA.
Siguientes pasos
- La guía de IIS tiene el mismo problema en un grupo de aplicaciones (el evento 5021 de WAS) y la misma solución.
- La primera guía de Windows Server explica cómo leer el visor de eventos con filtros como los de aquí.
- Las cuentas de servicio que no pueden ser gMSA son candidatas a un gestor de acceso privilegiado con rotación automática, como el de la guía de CyberArk del Nivel 4.
¿Falta algo o en tu entorno es distinto? Escríbeme y lo corrijo.
What you'll get
Moving services and scheduled tasks off svc- accounts whose password somebody wrote in a spreadsheet years ago, and onto group Managed Service Accounts (gMSA): Active Directory generates and changes the password by itself, and only authorised servers can use it. And, while any old account is left, solving in ten minutes the ticket about a service that won't start because someone changed its password.
Before you start
- A domain with Windows Server 2012 or later domain controllers (any supported version meets this).
- Permissions to create objects in
OU=Service Accounts,DC=contoso,DC=localand, once per forest, someone in Enterprise Admins or Domain Admins for the KDS key. - On every server that uses the gMSA, the AD module:
Install-WindowsFeature RSAT-AD-PowerShell. - An inventory of what runs under domain accounts. Start here:
Get-CimInstance Win32_Service | Where-Object StartName -like 'CONTOSO\*' | Select-Object Name, StartName, State, StartModeName StartName State StartMode---- --------- ----- ---------ContosoInvoices CONTOSO\svc-invoices Running AutoGet-ScheduledTask | Where-Object { $_.Principal.UserId -like '*svc-*' } | Select-Object TaskPath, TaskName, @{n='Account';e={$_.Principal.UserId}}TaskPath TaskName Account-------- -------- -------\Contoso\ Export invoices CONTOSO\svc-invoices1. Which account to use
| Account | Where it works | Password | When |
|---|---|---|---|
Virtual account (NT SERVICE\Service) | Only on that server; on the network, as the computer account | None | The service does not need to reach other servers |
Domain user account (svc-) | Any server | You set it and change it | Only if the application supports nothing else |
gMSA (gmsa-reports$) | The servers in the allowed group | AD generates it (240 characters) and changes it every 30 days | A service, task or IIS pool that reaches SQL Server, a share or AD |
One gMSA per application, not one for everything: if it is misused, the blast radius is one application.
2. The KDS root key (once per forest)
Domain controllers derive gMSA passwords from a KDS root key. Check whether one already exists:
Get-KdsRootKeyAdd-KdsRootKey -EffectiveImmediatelyGuid----4e1b5c3a-8d2f-4b6e-9a71-0c3d5e7f9b12- With
-EffectiveImmediately, the key can not be used until 10 hours later: that is the margin for it to replicate to every DC. Create it the day before. - In a lab with a single DC you can skip the wait with
Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10)). Not in production.
3. Create the gMSA
First a group with the servers that will be able to use it; then the account:
New-ADGroup -Name 'GG-gMSA-Reports' -GroupScope Global -Path 'OU=Service Accounts,DC=contoso,DC=local'Add-ADGroupMember -Identity 'GG-gMSA-Reports' -Members 'SRV-MGMT01$'New-ADServiceAccount -Name 'gmsa-reports' -DNSHostName 'gmsa-reports.contoso.local' -PrincipalsAllowedToRetrieveManagedPassword 'GG-gMSA-Reports' -Path 'OU=Service Accounts,DC=contoso,DC=local'Get-ADServiceAccount gmsa-reports -Properties PrincipalsAllowedToRetrieveManagedPassword, ManagedPasswordIntervalInDays | Select-Object Name, ManagedPasswordIntervalInDays, PrincipalsAllowedToRetrieveManagedPasswordName ManagedPasswordIntervalInDays PrincipalsAllowedToRetrieveManagedPassword---- ----------------------------- ------------------------------------------gmsa-reports 30 {CN=GG-gMSA-Reports,OU=Service Accounts,DC=contoso,DC=local}- The name has a maximum of 15 characters: it is the
sAMAccountName, to which AD adds the$. - A server you have just added to the group does not know until it renews its Kerberos ticket: restart it or, without restarting, run
klist -li 0x3e7 purgeon that server.
4. Install and test on the server
Install-ADServiceAccount gmsa-reportsTest-ADServiceAccount gmsa-reportsTrueTrue means this server can ask AD for the password. False is almost always one of three: the server is not in the group, it has not renewed its ticket since you added it, or the KDS key is not effective yet.
5. Assign it to a service
In services.msc, the service › Properties › Log On:
From the command line, in a cmd console (in Windows PowerShell 5.1 empty quotes do not reach sc.exe):
sc.exe config ContosoReports obj= "CONTOSO\gmsa-reports$" password= ""[SC] ChangeServiceConfig SUCCESSsc.exe stop ContosoReports && sc.exe start ContosoReportssc.exedoes not grant the Log on as a service right: if you use it, grant it through GPO under User Rights Assignment or the service will not start (event 7041).- Then the permissions the application needs, to the gMSA and nothing more: its SQL Server database (
CREATE LOGIN [CONTOSO\gmsa-reports$] FROM WINDOWS), its share, its OU.
6. Assign it to a scheduled task
The Task Scheduler interface asks for a password and does not work for a gMSA. With PowerShell:
$runas = New-ScheduledTaskPrincipal -UserId 'CONTOSO\gmsa-reports$' -LogonType PasswordSet-ScheduledTask -TaskName 'Export reports' -TaskPath '\Contoso\' -Principal $runas(Get-ScheduledTask -TaskName 'Export reports' -TaskPath '\Contoso\').Principal | Select-Object UserId, LogonTypeUserId LogonType------ ---------gmsa-reports$ PasswordThe gMSA needs the Log on as a batch job right on the server. A complete example of a task with a gMSA, with the script and its checks, is in the weekly Active Directory report with PowerShell.
7. The ticket: "the service won't start after the password change"
Monday, 7:50. The invoicing app is not responding. On srv-app02, the ContosoInvoices service is stopped and starting it gives: Error 1069: The service did not start due to a logon failure.
Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='Service Control Manager'; Id=7000,7038,7041; StartTime=(Get-Date).AddDays(-3)} | Select-Object TimeCreated, Id, Message -First 2 | Format-ListTimeCreated : 03/11/2026 7:52:10Id : 7038Message : The ContosoInvoices service was unable to log on as CONTOSO\svc-invoices with the currently configured password due to the following error: The user name or password is incorrect.TimeCreated : 03/11/2026 7:52:10Id : 7000Message : The ContosoInvoices service failed to start due to the following error: The service did not start due to a logon failure.- 7038 + 7000: the password stored in the service is no longer the one in AD.
- 7041: the password is fine, but the account is missing the Log on as a service right (a security GPO has overwritten it).
Then the account in AD:
Get-ADUser svc-invoices -Properties PasswordLastSet, LockedOut, Enabled, AccountExpirationDate | Select-Object Enabled, LockedOut, PasswordLastSet, AccountExpirationDateEnabled LockedOut PasswordLastSet AccountExpirationDate------- --------- --------------- --------------------- True True 31/10/2026 18:04:33The password was changed on Friday (PasswordLastSet) and the account is locked out: the service, and probably other servers using the same account, keep trying the old password. That is why the inventory at the start matters: it has to be changed in every place it is used, or the account locks again within minutes.
- The new password, from the team's password manager (or from the application owner).
- On every server and every task that uses
svc-invoices: Properties › Log On with the new password (orsc.exe config ContosoInvoices obj= "CONTOSO\svc-invoices" password= "..."from cmd). Unlock-ADAccount svc-invoicesandStart-Service ContosoInvoices. Check that the app responds and that there are no new 7038 events.- The real fix, in a planned change: a
gmsa-invoicesgMSA following steps 3 to 6, permissions in SQL Server, and thesvc-invoicesaccount disabled after two weeks unused.
If the service already ran under a gMSA and gives 7000, the cause is different: Test-ADServiceAccount on that server. It is nearly always a new or rebuilt server that nobody added to the GG-gMSA-... group.
In the ticket: service, events, account state, where the password was changed and the proposal to move to a gMSA.
Next steps
- The IIS guide has the same problem on an application pool (WAS event 5021) and the same solution.
- The first Windows Server guide explains how to read Event Viewer with filters like the ones here.
- Service accounts that cannot become gMSAs are candidates for a privileged access manager with automatic rotation, like the one in the Level 4 CyberArk guide.
Is something missing, or different in your environment? Get in touch and I'll fix it.
Tech Career Lab · newsletter
¿Te ha servido? Cada dos semanas envío una idea práctica para perfiles IT: LinkedIn, proyectos, networking y procesos de selección.Found this useful? Every two weeks I send one practical idea for IT professionals: LinkedIn, projects, networking and hiring processes.
Apúntate y llévate las 33 ideasSign up and get the 33 ideas →