Change Report Server Service Account - dsccommunity/SqlServerDsc GitHub Wiki
This guide walks you through changing the service account for Power BI Report Server (PBIRS) or SQL Server Reporting Services (SSRS) using SqlServerDsc PowerShell commands. Changing the service account is a multi-step process that requires careful handling of encryption keys, database permissions, and URL reservations.
This guide applies to SQL Server 2019 Reporting Services, SQL Server 2022 Reporting Services, and Power BI Report Server. SQL Server 2017 Reporting Services is no longer supported as mainstream support has ended.
[!NOTE] The examples in this guide use the instance name
'SSRS'for SQL Server Reporting Services. If you are using Power BI Report Server or have a custom instance name, substitute'SSRS'with your instance name (e.g.,'PBIRS'or your custom name).
Why Is This Process Complex?
When you change the Report Server service account, three interconnected systems are affected:
-
Encryption Keys — Report Server uses a symmetric encryption key to protect sensitive data stored in the database (such as stored credentials for data sources and connection strings). This key is tied to the service account's Windows security context. The new account cannot decrypt data encrypted by the old account.
-
Database Permissions — The Report Server databases (
ReportServerandReportServerTempDB) grant permissions to the service account. The new account has no access until you explicitly grant it. -
URL Reservations — URL reservations in HTTP.sys are registered with the service account's Security Identifier (SID). After changing accounts, the old reservations reference a SID that no longer matches the running service.
Failing to address any of these will leave your Report Server in a broken state.
Prerequisites
Before starting, ensure you have:
-
SqlServerDsc module installed — Install from PowerShell Gallery:
Install-PSResource -Name 'SqlServerDsc' -Scope 'AllUsers' -TrustRepository -
An existing, initialized Report Server instance — The instance must be fully configured with database connection established and the server initialized.
-
The new service account created — The Windows or Active Directory account must exist before you begin. For domain accounts, use the format
DOMAIN\Username. -
SQL Server access — You need permissions to create logins and execute scripts on the SQL Server instance hosting the Report Server databases.
-
Administrator privileges — Run PowerShell as Administrator on the Report Server machine.
The Complete Workflow
The service account change process consists of eight steps that must be executed in order. The key insight is to backup the encryption key before changing the service account, then restore it after granting database permissions.
| Step | Action | Command |
|---|---|---|
| 1 | Backup encryption key | Backup-SqlDscRSEncryptionKey |
| 2 | Change the service account | Set-SqlDscRSServiceAccount |
| 3 | Verify the change | Get-SqlDscRSServiceAccount |
| 4 | Grant database permissions | New-SqlDscLogin, Request-SqlDscRSDatabaseRightsScript, Invoke-SqlDscQuery |
| 5 | Restore encryption key | Restore-SqlDscRSEncryptionKey |
| 6 | Recreate URL reservations | Set-SqlDscRSUrlReservation -RecreateExisting |
| 7 | Re-initialize the Report Server | Initialize-SqlDscRS |
| 8 | Validate accessibility | Test-SqlDscRSAccessible |
Step 1: Backup Encryption Key
Before making any changes, backup the current encryption key. This backup allows you to restore the key after changing the service account, preserving all encrypted data including stored credentials, connection strings, and subscription settings.
[!TIP] Back up your encryption key regularly using
Backup-SqlDscRSEncryptionKey, especially after any configuration changes. Store backups securely in multiple locations for disaster recovery.
$configuration = Get-SqlDscRSConfiguration -InstanceName 'SSRS'
$backupPassword = Read-Host -Prompt 'Enter a password to protect the encryption key backup' -AsSecureString
$backupPath = Join-Path -Path $env:TEMP -ChildPath 'RSEncryptionKey.snk'
$backupSqlDscRSEncryptionKeyParams = @{
Path = $backupPath
Password = $backupPassword
Force = $true
}
$configuration | Backup-SqlDscRSEncryptionKey @backupSqlDscRSEncryptionKeyParams
Parameters explained:
-Path— The file path where the encryption key backup will be saved.-Password— ASecureStringpassword used to encrypt the backup file. This password will be required when restoring the key.-Force— Overwrites an existing backup file if present.
[!IMPORTANT] Store the backup password securely. Without this password, you cannot restore the encryption key. Consider using a password manager or secure vault to store the password, and avoid hardcoding passwords in scripts.
What happens internally:
This command calls the WMI method BackupEncryptionKey, which exports the
symmetric encryption key to a password-protected file.
Step 2: Change the Service Account
Change the service account using Set-SqlDscRSServiceAccount.
$newCredential = Get-Credential -Message 'Enter the new service account credentials (DOMAIN\Username)'
$setRSServiceAccountParams = @{
Credential = $newCredential
RestartService = $true
SuppressUrlReservationWarning = $true
Force = $true
}
$configuration | Set-SqlDscRSServiceAccount @setRSServiceAccountParams
Parameters explained:
-Credential— APSCredentialobject containing the new service account username and password.-RestartService— Automatically restarts the Report Server service after the change.-SuppressUrlReservationWarning— Suppresses the warning about URL reservations needing to be updated (we handle this in Step 6).-Force— Skips confirmation prompts for automation scenarios.
What happens internally:
This command calls the WMI method SetWindowsServiceIdentity, which:
- Updates the Windows service to run under the new account
- Sets appropriate file permissions on the Report Server installation directory
- Grants the
LogonAsServiceright to the new account
[!IMPORTANT] After this step, the new account does NOT yet have database access, and the encryption key is still tied to the old account. The Report Server will not function correctly until all remaining steps are completed.
Step 3: Verify the Service Account Change
Confirm that the service account was changed successfully:
$configuration = Get-SqlDscRSConfiguration -InstanceName 'SSRS'
$currentServiceAccount = $configuration | Get-SqlDscRSServiceAccount
Write-Information -MessageData "Service account is now: $currentServiceAccount" -InformationAction 'Continue'
The returned value should match the username you specified in Step 2.
Step 4: Grant Database Permissions
The new service account needs permissions to access the Report Server databases. This involves three sub-steps.
4a. Create a SQL Server Login for the New Account
Connect to the SQL Server instance hosting the Report Server databases and create a login for the new service account:
$serverObject = Connect-SqlDscDatabaseEngine -ServerName 'localhost' -InstanceName 'RSDB'
New-SqlDscLogin -ServerObject $serverObject -Name $currentServiceAccount -WindowsUser -Force
Disconnect-SqlDscDatabaseEngine -ServerObject $serverObject
[!NOTE] Replace
'localhost'and'RSDB'with your actual SQL Server name and instance name. If using the default instance, omit-InstanceNameor use'MSSQLSERVER'.
4b. Generate and Execute the Database Rights Script
Request the database rights script from Report Server and execute it:
$databaseName = $configuration.DatabaseName
$requestSqlDscRSDatabaseRightsScriptParams = @{
DatabaseName = $databaseName
UserName = $currentServiceAccount
}
$databaseRightsScript = $configuration | Request-SqlDscRSDatabaseRightsScript @requestSqlDscRSDatabaseRightsScriptParams
$invokeSqlDscQueryParams = @{
ServerName = 'localhost'
InstanceName = 'RSDB'
DatabaseName = 'master'
Query = $databaseRightsScript
Force = $true
}
Invoke-SqlDscQuery @invokeSqlDscQueryParams
[!NOTE] For more details on the
-UserNameparameter and the permissions granted, see GenerateDatabaseRightsScript Method.
4c. Restart the Report Server Service
Restart the service to apply the new database permissions:
$configuration | Restart-SqlDscRSService -Force
After this step, the Report Server can connect to its databases using the new service account.
Step 5: Restore Encryption Key
Restore the encryption key that was backed up in Step 1. This allows the new service account to decrypt all previously encrypted data.
$restoreSqlDscRSEncryptionKeyParams = @{
Path = $backupPath
Password = $backupPassword
Force = $true
}
$configuration | Restore-SqlDscRSEncryptionKey @restoreSqlDscRSEncryptionKeyParams
Parameters explained:
-Path— The file path to the encryption key backup created in Step 1.-Password— TheSecureStringpassword used when creating the backup.-Force— Skips confirmation prompts for automation scenarios.
What happens internally:
This command calls the WMI method RestoreEncryptionKey, which:
- Imports the symmetric encryption key from the backup file
- Associates the key with the new service account's security context
- Enables the Report Server to decrypt all previously encrypted data
[!IMPORTANT] Unlike the destructive approach of removing and recreating the encryption key, restoring from backup preserves all encrypted data including stored credentials, connection strings, and subscription settings.
Alternative: Fresh Start (Destructive)
If you do not have an encryption key backup or prefer to start fresh, you can remove the existing encryption key and create a new one. This is a destructive operation — all encrypted data will be lost.
[!WARNING] This approach deletes all stored credentials, connection strings with embedded credentials, subscription delivery settings with credentials, and unattended execution account credentials. You must re-enter all credentials after completing the service account change.
$configuration | Remove-SqlDscRSEncryptionKey -Force
$configuration | New-SqlDscRSEncryptionKey -Force
The Remove-SqlDscRSEncryptionKey command calls the WMI method DeleteEncryptionKey,
and New-SqlDscRSEncryptionKey calls ReencryptSecureInformation to create a
new symmetric key associated with the new service account.
Step 6: Recreate URL Reservations
URL reservations in HTTP.sys are registered with the service account's Security Identifier (SID). After changing accounts, you must recreate all URL reservations to register them with the new account's SID:
$configuration | Set-SqlDscRSUrlReservation -RecreateExisting -Force
$configuration | Restart-SqlDscRSService -Force
The -RecreateExisting parameter instructs the command to:
- Retrieve all current URL reservations
- Remove each reservation from HTTP.sys
- Re-add each reservation (now registered to the new account's SID)
This ensures the Report Server service can bind to its configured URLs.
Step 7: Re-Initialize the Report Server
Re-initialize the Report Server to validate all configuration settings and ensure the server is ready to handle requests:
$configuration | Initialize-SqlDscRS -Force
$configuration | Restart-SqlDscRSService -Force
This calls the WMI method InitializeReportServer, which performs internal
validation and prepares the server for operation.
Step 8: Validate Accessibility
Finally, verify that the Report Server is fully operational:
$configuration = Get-SqlDscRSConfiguration -InstanceName 'SSRS'
$finalServiceAccount = $configuration | Get-SqlDscRSServiceAccount
Write-Information -MessageData "Service account: $finalServiceAccount" -InformationAction 'Continue'
$isInitialized = $configuration | Test-SqlDscRSInitialized
Write-Information -MessageData "Is initialized: $isInitialized" -InformationAction 'Continue'
$urlReservations = $configuration | Get-SqlDscRSUrlReservation
Write-Information -MessageData "URL reservations configured: $($urlReservations.Count)" -InformationAction 'Continue'
$configuration | Test-SqlDscRSAccessible -Detailed -TimeoutSeconds 240 -RetryIntervalSeconds 10
The Test-SqlDscRSAccessible command tests HTTP connectivity to all configured
Report Server URLs and returns the accessibility status. The -Detailed parameter
provides verbose output about each URL tested.
[!TIP] After successfully completing the service account change, create a fresh backup of the encryption key using
Backup-SqlDscRSEncryptionKey. Store this backup securely for future disaster recovery scenarios.
Complete Script
Here is the complete script combining all steps. Copy and customize for your environment:
#Requires -Modules SqlServerDsc
#Requires -RunAsAdministrator
$instanceName = 'SSRS' # Report Server instance name
$dbServerName = 'localhost' # SQL Server hosting RS databases
$dbInstanceName = 'RSDB' # SQL instance name (or 'MSSQLSERVER' for default)
$newCredential = Get-Credential -Message 'Enter the new service account credentials (DOMAIN\Username)'
$configuration = Get-SqlDscRSConfiguration -InstanceName $instanceName
Write-Information -MessageData "Current service account: $($configuration.WindowsServiceIdentityActual)" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 1] Backing up encryption key..." -InformationAction 'Continue'
$backupPassword = Read-Host -Prompt 'Enter a password to protect the encryption key backup' -AsSecureString
$backupPath = Join-Path -Path $env:TEMP -ChildPath 'RSEncryptionKey.snk'
$backupSqlDscRSEncryptionKeyParams = @{
Path = $backupPath
Password = $backupPassword
Force = $true
}
$configuration | Backup-SqlDscRSEncryptionKey @backupSqlDscRSEncryptionKeyParams
Write-Information -MessageData "Encryption key backed up to: $backupPath" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 2] Changing service account..." -InformationAction 'Continue'
$setSqlDscRSServiceAccountParams = @{
Credential = $newCredential
RestartService = $true
SuppressUrlReservationWarning = $true
Force = $true
}
$configuration | Set-SqlDscRSServiceAccount @setSqlDscRSServiceAccountParams
Write-Information -MessageData "`n[Step 3] Verifying service account change..." -InformationAction 'Continue'
$configuration = Get-SqlDscRSConfiguration -InstanceName $instanceName
$currentServiceAccount = $configuration | Get-SqlDscRSServiceAccount
Write-Information -MessageData "Service account is now: $currentServiceAccount" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 4] Granting database permissions..." -InformationAction 'Continue'
$serverObject = Connect-SqlDscDatabaseEngine -ServerName $dbServerName -InstanceName $dbInstanceName
New-SqlDscLogin -ServerObject $serverObject -Name $currentServiceAccount -WindowsUser -Force
Disconnect-SqlDscDatabaseEngine -ServerObject $serverObject
$databaseName = $configuration.DatabaseName
$requestSqlDscRSDatabaseRightsScriptParams = @{
DatabaseName = $databaseName
UserName = $currentServiceAccount
}
$databaseRightsScript = $configuration | Request-SqlDscRSDatabaseRightsScript @requestSqlDscRSDatabaseRightsScriptParams
$invokeSqlDscQueryParams = @{
ServerName = $dbServerName
InstanceName = $dbInstanceName
DatabaseName = 'master'
Query = $databaseRightsScript
Force = $true
}
Invoke-SqlDscQuery @invokeSqlDscQueryParams
$configuration | Restart-SqlDscRSService -Force
Write-Information -MessageData "Database permissions granted" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 5] Restoring encryption key..." -InformationAction 'Continue'
$restoreSqlDscRSEncryptionKeyParams = @{
Path = $backupPath
Password = $backupPassword
Force = $true
}
$configuration | Restore-SqlDscRSEncryptionKey @restoreSqlDscRSEncryptionKeyParams
Write-Information -MessageData "Encryption key restored" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 6] Recreating URL reservations..." -InformationAction 'Continue'
$configuration | Set-SqlDscRSUrlReservation -RecreateExisting -Force
$configuration | Restart-SqlDscRSService -Force
Write-Information -MessageData "URL reservations recreated" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 7] Re-initializing Report Server..." -InformationAction 'Continue'
$configuration | Initialize-SqlDscRS -Force
$configuration | Restart-SqlDscRSService -Force
Write-Information -MessageData "Report Server re-initialized" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 8] Validating accessibility..." -InformationAction 'Continue'
$configuration = Get-SqlDscRSConfiguration -InstanceName $instanceName
$finalServiceAccount = $configuration | Get-SqlDscRSServiceAccount
$isInitialized = $configuration | Test-SqlDscRSInitialized
$urlReservations = $configuration | Get-SqlDscRSUrlReservation
Write-Information -MessageData "`nFinal Status:" -InformationAction 'Continue'
Write-Information -MessageData " Service Account: $finalServiceAccount" -InformationAction 'Continue'
Write-Information -MessageData " Is Initialized: $isInitialized" -InformationAction 'Continue'
Write-Information -MessageData " URL Reservations: $($urlReservations.Count)" -InformationAction 'Continue'
Write-Information -MessageData "`nTesting HTTP accessibility..." -InformationAction 'Continue'
$configuration | Test-SqlDscRSAccessible -Detailed -TimeoutSeconds 240 -RetryIntervalSeconds 10
Write-Information -MessageData "`n[Complete] Service account change finished successfully!" -InformationAction 'Continue'
Alternative: Destructive Key Replacement Script
If you do not have an encryption key backup or prefer to start fresh with a new key, use this alternative script. This approach is destructive — all encrypted data including stored credentials will be lost and must be re-entered after completion.
#Requires -Modules SqlServerDsc
#Requires -RunAsAdministrator
$instanceName = 'SSRS'
$dbServerName = 'localhost'
$dbInstanceName = 'RSDB'
$newCredential = Get-Credential -Message 'Enter the new service account credentials (DOMAIN\Username)'
$configuration = Get-SqlDscRSConfiguration -InstanceName $instanceName
Write-Information -MessageData "Current service account: $($configuration.WindowsServiceIdentityActual)" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 1] Changing service account..." -InformationAction 'Continue'
$setSqlDscRSServiceAccountParams = @{
Credential = $newCredential
RestartService = $true
SuppressUrlReservationWarning = $true
Force = $true
}
$configuration | Set-SqlDscRSServiceAccount @setSqlDscRSServiceAccountParams
Write-Information -MessageData "`n[Step 2] Verifying service account change..." -InformationAction 'Continue'
$configuration = Get-SqlDscRSConfiguration -InstanceName $instanceName
$currentServiceAccount = $configuration | Get-SqlDscRSServiceAccount
Write-Information -MessageData "Service account is now: $currentServiceAccount" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 3] Granting database permissions..." -InformationAction 'Continue'
$serverObject = Connect-SqlDscDatabaseEngine -ServerName $dbServerName -InstanceName $dbInstanceName
New-SqlDscLogin -ServerObject $serverObject -Name $currentServiceAccount -WindowsUser -Force
Disconnect-SqlDscDatabaseEngine -ServerObject $serverObject
$databaseName = $configuration.DatabaseName
$requestSqlDscRSDatabaseRightsScriptParams = @{
DatabaseName = $databaseName
UserName = $currentServiceAccount
}
$databaseRightsScript = $configuration | Request-SqlDscRSDatabaseRightsScript @requestSqlDscRSDatabaseRightsScriptParams
$invokeSqlDscQueryParams = @{
ServerName = $dbServerName
InstanceName = $dbInstanceName
DatabaseName = 'master'
Query = $databaseRightsScript
Force = $true
}
Invoke-SqlDscQuery @invokeSqlDscQueryParams
$configuration | Restart-SqlDscRSService -Force
Write-Information -MessageData "Database permissions granted" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 4] Removing old encryption key (DESTRUCTIVE)..." -InformationAction 'Continue'
$configuration | Remove-SqlDscRSEncryptionKey -Force
Write-Information -MessageData "Old encryption key removed" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 5] Creating new encryption key..." -InformationAction 'Continue'
$configuration | New-SqlDscRSEncryptionKey -Force
Write-Information -MessageData "New encryption key created" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 6] Recreating URL reservations..." -InformationAction 'Continue'
$configuration | Set-SqlDscRSUrlReservation -RecreateExisting -Force
$configuration | Restart-SqlDscRSService -Force
Write-Information -MessageData "URL reservations recreated" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 7] Re-initializing Report Server..." -InformationAction 'Continue'
$configuration | Initialize-SqlDscRS -Force
$configuration | Restart-SqlDscRSService -Force
Write-Information -MessageData "Report Server re-initialized" -InformationAction 'Continue'
Write-Information -MessageData "`n[Step 8] Validating accessibility..." -InformationAction 'Continue'
$configuration = Get-SqlDscRSConfiguration -InstanceName $instanceName
$finalServiceAccount = $configuration | Get-SqlDscRSServiceAccount
$isInitialized = $configuration | Test-SqlDscRSInitialized
$urlReservations = $configuration | Get-SqlDscRSUrlReservation
Write-Information -MessageData "`nFinal Status:" -InformationAction 'Continue'
Write-Information -MessageData " Service Account: $finalServiceAccount" -InformationAction 'Continue'
Write-Information -MessageData " Is Initialized: $isInitialized" -InformationAction 'Continue'
Write-Information -MessageData " URL Reservations: $($urlReservations.Count)" -InformationAction 'Continue'
Write-Information -MessageData "`nTesting HTTP accessibility..." -InformationAction 'Continue'
$configuration | Test-SqlDscRSAccessible -Detailed -TimeoutSeconds 240 -RetryIntervalSeconds 10
Write-Information -MessageData "`n[Complete] Service account change finished!" -InformationAction 'Continue'
Write-Information -MessageData "`n[ACTION REQUIRED] Re-enter all stored credentials for data sources and subscriptions." -InformationAction 'Continue'
Important Considerations
Plan for Downtime
The Report Server will be unavailable during this process. Plan to perform this change during a maintenance window when users do not need access to reports.
Test in Non-Production First
Always test this procedure in a non-production environment before applying it to production servers. Verify that reports, subscriptions, and data sources function correctly after the change.
Document Your Configuration
Before making changes, document your current configuration including:
- Current service account
- Database server and instance names
- URL reservations
- Any custom SSL certificate bindings
This information is invaluable for troubleshooting if issues arise.
Summary
Changing the service account for SQL Server Reporting Services or Power BI Report Server requires a methodical approach that addresses encryption keys, database permissions, and URL reservations. By following this eight-step process using SqlServerDsc commands, you can automate this change reliably and consistently across your Report Server infrastructure.
The key takeaways are:
- Backup the encryption key before changing the service account — this preserves all encrypted data and is the recommended approach
- The process must be performed in order — each step depends on the previous
- The destructive approach (remove/create key) should only be used when no backup exists or when starting fresh is acceptable
- Always validate accessibility after completing all steps
- Plan for service downtime during the change