- 3 minutes to read

Migrate Traditional Service Account to gMSA

Use this guide when you already run Nodinite with a traditional service account and want to switch to gMSA without losing encrypted configuration access.

Understanding Certificate Store Migration

Traditional service accounts and gMSA accounts use different certificate store contexts. You must move certificates before you switch identities.

flowchart TB OLD[" Traditional Service Account"] --> CUR["CurrentUser\\My"] CUR --> EXP[" Export PFX"] EXP --> IMP[" Import PFX"] IMP --> LM["LocalMachine\\My"] LM --> ACL[" Grant Private Key Read"] ACL --> GMSA[" gMSA Identity"] GMSA --> IIS[" IIS Application Pools"] GMSA --> SVC[" Windows Services"] style OLD fill:#87CEEB style CUR fill:#FFD700 style LM fill:#FFD700 style GMSA fill:#90EE90 style ACL fill:#90EE90

Example of certificate flow during migration from CurrentUser to LocalMachine for gMSA-based service identities.

Migration Workflow

  1. Export certificates from the old account's Cert:\CurrentUser\My store.
  2. Import certificates into Cert:\LocalMachine\My.
  3. Grant the gMSA account read access to certificate private keys.
  4. Update Nodinite service identities to use gMSA.
  5. Verify IIS application pools, Windows Services, and encrypted configuration access.

Step 1: Export Certificates from CurrentUser Store

Run PowerShell as the old service account:

Get-ChildItem Cert:\CurrentUser\My |
  Where-Object { $_.Subject -like "*Nodinite*" -or $_.FriendlyName -like "*Nodinite*" } |
  Format-List Subject, Thumbprint, NotAfter, FriendlyName

$certThumbprint = "1234567890ABCDEF1234567890ABCDEF12345678"
$cert = Get-ChildItem Cert:\CurrentUser\My\$certThumbprint

if ($null -eq $cert) {
    Write-Error "Certificate not found in CurrentUser store"
    exit
}

$pfxPassword = ConvertTo-SecureString -String "SecurePassword123!" -Force -AsPlainText
$pfxPath = "C:\Temp\NodiniteCert_$certThumbprint.pfx"
Export-PfxCertificate -Cert $cert -FilePath $pfxPath -Password $pfxPassword

Step 2: Import Certificates into LocalMachine Store

Run PowerShell as Administrator:

$pfxPath = "C:\Temp\NodiniteCert_1234567890ABCDEF1234567890ABCDEF12345678.pfx"
$pfxPassword = ConvertTo-SecureString -String "SecurePassword123!" -Force -AsPlainText

$cert = Import-PfxCertificate -FilePath $pfxPath -CertStoreLocation Cert:\LocalMachine\My -Password $pfxPassword -Exportable

Write-Host "Imported: $($cert.Thumbprint)" -ForegroundColor Green
Remove-Item $pfxPath -Force

Step 3: Grant gMSA Private Key Permissions

Run PowerShell as Administrator:

$gmsaAccount = "CONTOSO\NodiniteProdSvc$"
$certThumbprint = "1234567890ABCDEF1234567890ABCDEF12345678"

$cert = Get-ChildItem Cert:\LocalMachine\My\$certThumbprint
if ($null -eq $cert) {
    Write-Error "Certificate not found in LocalMachine store"
    exit
}

$privateKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
$privateKeyFile = "$env:ProgramData\Microsoft\Crypto\RSA\MachineKeys\$($privateKey.Key.UniqueName)"

$acl = Get-Acl -Path $privateKeyFile
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($gmsaAccount, "Read", "Allow")
$acl.SetAccessRule($rule)
Set-Acl -Path $privateKeyFile -AclObject $acl

For detailed certificate ACL guidance, see Microsoft: Grant access to a certificate private key.

Step 4: Update Service Identities to gMSA

Use Nodinite Portal:

  1. Download the OLD package for the current version. Ensure no changes were already made. If you have the old package, prefer to use that one as that will be your safeset option.
  2. Uninstall the current version using the OLD package.
  3. Open Environment -> Service Accounts.
  4. Select Use gMSA Account.
  5. Enter the account in format DOMAIN\gMSAName$.
  6. Save changes.
  7. Download new package.
  8. Install using the script in new package.

Step 5: Verify Migration

$certThumbprint = "1234567890ABCDEF1234567890ABCDEF12345678"
Get-ChildItem Cert:\LocalMachine\My\$certThumbprint | Format-List Subject, Thumbprint, HasPrivateKey, NotAfter

Import-Module WebAdministration
Get-ChildItem IIS:\AppPools |
  Where-Object { $_.Name -like "Nodinite*" } |
  Select-Object Name, State, @{n="Identity";e={$_.ProcessModel.UserName}}

Then verify Web Client login, monitoring, logging, and encrypted configuration behavior.

Next Step