How to Manage Service Accounts in Active Directory on Windows Server 2012 R2
Service accounts are domain accounts used by applications, services, and automated tasks to authenticate to Windows resources. Poorly managed service accounts are one of the most common attack vectors in enterprise environments — they often have excessive privileges, passwords that never expire, and credentials stored in plain text in scripts or configuration files. Windows Server 2012 R2 provides multiple options for service account management, from traditional user accounts to Managed Service Accounts (MSAs) and Group Managed Service Accounts (gMSAs). This guide covers the management of traditional service accounts and the principles that govern their secure use, before the more detailed gMSA treatment in subsequent guides.
Prerequisites
Domain Admin or Account Operator rights are required to create and manage service accounts. The ActiveDirectory module must be available. A well-defined OU structure should include a dedicated ServiceAccounts OU separate from regular user accounts to simplify management and GPO application.
Import-Module ActiveDirectory
# Create a dedicated Service Accounts OU
New-ADOrganizationalUnit -Name "ServiceAccounts" `
-Path "OU=Contoso,DC=contoso,DC=com" `
-ProtectedFromAccidentalDeletion $true
Creating Service Accounts Following Least Privilege
Service accounts should be created with only the permissions required for the service to function. Avoid using Domain Admin accounts as service accounts. Create dedicated accounts with descriptive naming conventions:
# Naming convention: svc--
# Examples: svc-sql-prod, svc-iis-dev, svc-backup-prod
New-ADUser `
-Name "svc-sql-prod" `
-SamAccountName "svc-sql-prod" `
-UserPrincipalName "[email protected]" `
-Path "OU=ServiceAccounts,OU=Contoso,DC=contoso,DC=com" `
-AccountPassword (ConvertTo-SecureString "C0mplexSvcP@ss2024!" -AsPlainText -Force) `
-Enabled $true `
-PasswordNeverExpires $true `
-CannotChangePassword $true `
-Description "SQL Server service account - Production DB01"
New-ADUser `
-Name "svc-iis-prod" `
-SamAccountName "svc-iis-prod" `
-UserPrincipalName "[email protected]" `
-Path "OU=ServiceAccounts,OU=Contoso,DC=contoso,DC=com" `
-AccountPassword (ConvertTo-SecureString "W3bSvc@Pass2024!" -AsPlainText -Force) `
-Enabled $true `
-PasswordNeverExpires $true `
-CannotChangePassword $true `
-Description "IIS application pool account - Production Web01"
Configuring Service Account SPNs
Service Principal Names (SPNs) are required for Kerberos authentication to work with a service account. Services that accept Kerberos authentication must have an SPN registered in AD that maps the service type and hostname to the account running the service:
# Register an SPN for SQL Server service account
# Format: setspn -S ServiceClass/Host:Port AccountName
setspn -S MSSQLSvc/SQLDB01.contoso.com:1433 contososvc-sql-prod
setspn -S MSSQLSvc/SQLDB01.contoso.com contososvc-sql-prod
# Register HTTP SPN for IIS service account
setspn -S HTTP/web01.contoso.com contososvc-iis-prod
setspn -S HTTP/web01 contososvc-iis-prod
# List SPNs for a service account
setspn -L svc-sql-prod
# Check for duplicate SPNs (critical — duplicates cause Kerberos failures)
setspn -X
# Using PowerShell to set SPNs
Set-ADUser -Identity "svc-sql-prod" -ServicePrincipalNames @{
Add = "MSSQLSvc/SQLDB01.contoso.com:1433","MSSQLSvc/SQLDB01.contoso.com"
}
Configuring Delegation for Service Accounts
Kerberos delegation allows a service to present a user’s credentials to another backend service (e.g., a web server authenticating to a SQL server on behalf of a user). Three delegation modes exist:
Unconstrained delegation (least secure) — the service can delegate credentials to any service in the domain. Constrained delegation — the service can only delegate to specific services. Resource-based constrained delegation — the target service controls which accounts can delegate to it. Never configure unconstrained delegation on user-facing service accounts in production.
# Configure constrained delegation for IIS to SQL
# The IIS service account can delegate to the SQL service
Set-ADUser -Identity "svc-iis-prod" `
-Add @{
"msDS-AllowedToDelegateTo" = @(
"MSSQLSvc/SQLDB01.contoso.com:1433",
"MSSQLSvc/SQLDB01.contoso.com"
)
}
# Enable constrained delegation (Kerberos only)
Set-ADAccountControl -Identity "svc-iis-prod" `
-TrustedToAuthForDelegation $false
# Enable Kerberos-only constrained delegation
$account = Get-ADUser -Identity "svc-iis-prod"
Set-ADObject -Identity $account `
-Replace @{"userAccountControl" = ($account.userAccountControl.Value -bor 0x80000)}
Service Account Password Management
Managing passwords for traditional service accounts is a significant operational burden. Passwords must be rotated periodically, and the new password must be updated in every service, scheduled task, or application that uses the account. Create a process for this:
# Rotate a service account password
$newPassword = ConvertTo-SecureString "NewSvcP@ss2024!" -AsPlainText -Force
Set-ADAccountPassword -Identity "svc-sql-prod" `
-Reset `
-NewPassword $newPassword
# After resetting, update the service on the server
# This must be done on each server using the account
$credential = New-Object PSCredential("contososvc-sql-prod", $newPassword)
# Update via SC or Service Manager on target server
Invoke-Command -ComputerName "SQLDB01" -ScriptBlock {
$svc = Get-WmiObject Win32_Service -Filter "Name='MSSQLSERVER'"
$svc.Change($null,$null,$null,$null,$null,$null,"contososvc-sql-prod","NewSvcP@ss2024!")
Restart-Service MSSQLSERVER
}
Auditing and Inventory of Service Accounts
# List all service accounts (by OU)
Get-ADUser -SearchBase "OU=ServiceAccounts,OU=Contoso,DC=contoso,DC=com" `
-Filter * `
-Properties PasswordNeverExpires, PasswordLastSet, LastLogonDate,
ServicePrincipalNames, Description |
Select-Object Name, SamAccountName, PasswordLastSet, LastLogonDate,
PasswordNeverExpires, Description,
@{N="SPNs";E={$_.ServicePrincipalNames -join "; "}} |
Export-Csv "C:ReportsServiceAccounts.csv" -NoTypeInformation
# Find accounts with Kerberos delegation configured
Get-ADUser -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation |
Select-Object Name, SamAccountName
# Find accounts with unconstrained delegation (high risk)
Get-ADUser -Filter {TrustedForDelegation -eq $true} |
Select-Object Name, SamAccountName, DistinguishedName
Applying a Restrictive Group Policy to Service Accounts
Create a GPO linked to the ServiceAccounts OU to restrict where service accounts can log on interactively, preventing their misuse for regular work:
New-GPO -Name "ServiceAccounts-Restrictions"
New-GPLink -Name "ServiceAccounts-Restrictions" `
-Target "OU=ServiceAccounts,OU=Contoso,DC=contoso,DC=com"
In the GPO, configure User Configuration > Windows Settings > Security Settings > User Rights Assignment > Deny log on locally and Deny log on through Remote Desktop Services to include the service accounts group. This prevents administrators from using service account credentials for interactive logon.
Summary
Effective service account management in Active Directory on Windows Server 2012 R2 requires a combination of proper naming conventions, least-privilege configuration, SPN management for Kerberos, and controlled delegation settings. Traditional user-based service accounts carry significant management overhead due to password rotation requirements and credential sprawl. Consider migrating to Managed Service Accounts or Group Managed Service Accounts where supported, as these eliminate manual password management entirely. Maintain a current inventory of all service accounts, their purposes, and their privilege levels as a foundational security practice.