I recently built a new SCOM 2022 lab leveraging gMSA accounts. Included in my lab is an Always On Availability Group, SQL Failover Instance, and a standalone web console server. Ordinarily there’s not much fuss with setting up a web console but my lab uses gMSA accounts so there are a few more steps. This is not meant to be an exhaustive guide on SCOM installation, Windows cluster config, or SQL Always On, but rather just documentation of my notes for the next time so that I don’t have to reinvent the wheel. All computers are Windows Server 2022 Datacenter.
Accounts and Groups
gMSA Account | Description |
gMSA-SCOM-SQL$ | SQL service/SQL agent |
gMSA-OMDAS$ | Data Access Service |
gMSA-OMAA$ | Mgmt Server Action Account |
gMSA-OMDWRead$ | Data Reader (gMSA not officially supported by Microsoft) |
gMSA-OMDWWrite$ | Data Writer |
Global Security Group Name | Members (computers) | Description |
grpsec-SQL | SQL21 SQL22 SQL23 SQL24 SQLINST22 (cluster: SQL23, SQL24) AGL21 (AG Listener: SQL21, SQL22) | Computers in this group can retrieve the SQL service account password. |
grpsec-OpsManServers | MS21 MS22 SQLRPT21 | Computers in this group can retrieve the passwords for the SCOM service accounts . |
Standalone Web Server: WEB21
gMSA Stuff
Create Root Key for AD
# KDS Key for domain. Add this if it does not already exist.
Add-KdsRootKey -EffectiveImmediately
SQL Service Account
The OpsDB is destined for a SQL Always On Availability Group: SQL21,SQL22 with listener “AGL21”.
The DW is destined for a SQL Failover Cluster Instance: SQL23,SQL24 with SQL instance name: SQLINST21\INST1. These two SQL instances should provide me with some variety in my lab.
This is how I configured the SQL service account with PowerShell. I ran this code from the AD server because I happened to be logged into it at the time.
Set $accountName, $domain, $groupname, and $SQLservers.
(reference)
If you don’t have the AD Tools on your workstation, you can install the tools easily with this snippet:
# Run the following on each mgmt server.
Add-WindowsFeature -Name 'RSAT-AD-Tools' -Verbose
# Restart mgmt server
Restart-Computer -Force
$accountName = 'gMSA-SCOM-SQL' #No dollar '$' required on account name here.
$domain = 'CONTOSO.COM'
$groupname = 'grpsec-SQL' #computers in this group can retrieve the SQL account password
$SQLservers = 'sql21,sql22,sql23,sql24'
$params = @{
Name = $accountName
DNSHostName = "$($accountName).$($domain)"
PrincipalsAllowedToRetrieveManagedPassword = $groupname
ManagedPasswordIntervalInDays = 180
KerberosEncryptionType = 'RC4','AES128','AES256'
Enabled = $True
PassThru = $True
}
New-ADServiceAccount @params
# Give the account permissions to set own SPN
dsacls (Get-ADServiceAccount -Identity $accountName).DistinguishedName /G "SELF:RPWP;servicePrincipalName"
# Verify account for good measure
Get-ADServiceAccount $accountName -Properties * | FL DNSHostName,KerberosEncryptionType,SamAccountName
# Establish remote session on all affected/relevant servers to add the AD PowerShell tools. Required to install the gMSA account to the servers. You could run the command (within the scriptblock below) and then restart on each of the individual SQL servers. This is a slightly more fancy way of doing it.
$session = New-PSSession -ComputerName $SQLservers
Invoke-Command -Session $session -ScriptBlock {Add-WindowsFeature -Name 'RSAT-AD-Tools' -Verbose} -Verbose
# Restart is necessary for group membership to activate and required before we can use Install-ADServiceAccount command below.
Invoke-Command -Session $session -ScriptBlock {Restart-Computer -Force} -Verbose
# Allow the computers to use the account
$session = New-PSSession -ComputerName $SQLservers
# If this command below fails, log into each server and run the command manually
# Install-ADServiceAccount $accountName
Invoke-Command -Session $session -ScriptBlock {param ($accountname);Install-ADServiceAccount $accountName -Verbose} -ArgumentList $accountname
#Optionally you can test the service account from the SQL server. This command should return boolean "True".
Test-ADServiceAccount -Identity $accountName
SCOM Service Accounts
This is how I configured the 4 SCOM accounts and mgmt servers with PowerShell:
(reference1, reference2)
DAS/SDK: CONTOSO\gMSA-OMDAS$
OMAA: CONTOSO\gMSA-OMAA$
Reader: CONTOSO\gMSA-OMDWRead$
Writer: CONTOSO\gMSA-OMDWWrite$
Run the following snippet on each mgmt server.
# Run the following on each mgmt server. The AD Posh tools are needed to install the account to each server where they will be used.
Add-WindowsFeature -Name 'RSAT-AD-Tools' -Verbose
# Restart mgmt server
Restart-Computer -Force
I ran this account config code (below) from the AD server because I happened to be logged into the AD server at the time. In my lab the gMSA-OMDAS account object required the RC4 KerberosEncryptionType to be included (along with AES128 and AES256). Without it, the standalone Web Console Windows Authentication simply would not work. When RC4 is included, upon inspecting the ticket request and ticket reply with WireShark it appears that the ticket is, in fact, encrypted with AES256 (even when I disabled RC4 within Group Policy on the mgmt server and the web console server). I need someone smarter than me to explain this behavior.
Ticket Request
Ticket Reply
Run the following snippet for each of the 4 SCOM accounts.
Set $accountName, $domain, and $groupname as needed.
# SCOM account config example. Do this for each account.
$accountName = 'gMSA-OMDAS' #No dollar '$' required on account name here.
$domain = 'CONTOSO.COM'
$groupname = 'grpsec-OpsMgrSvrs' #computers in this group can retrieve the SCOM accounts passwords
$PrincipalsAllowedToRetrieveManagedPassword = $groupname
$params = @{
Name = $accountName
DNSHostName = "$($accountName).$($domain)"
PrincipalsAllowedToRetrieveManagedPassword = $PrincipalsAllowedToRetrieveManagedPassword
ManagedPasswordIntervalInDays = 180
KerberosEncryptionType = 'RC4','AES128','AES256'
Enabled = $True
PassThru = $True
}
New-ADServiceAccount @params
# Give permissions to set own SPN for applicable account(s)
dsacls (Get-ADServiceAccount -Identity $accountName).DistinguishedName /G "SELF:RPWP;servicePrincipalName"
# Verify account
Get-ADServiceAccount $accountName -Properties * | FL DNSHostName,KerberosEncryptionType,SamAccountName
I had to log into each mgmt server to run the commands below. I couldn’t get it to run in a fancy remote session and I got tired of trying.
Set $accountName as needed for each SCOM account.
This grants the server the ability to retrieve the passwords for each account.
# Run this for each SCOM service account on each mgmt server.
$accountName = 'gMSA-OMDAS' #example
Install-ADServiceAccount $accountName -Verbose
SQL
At this point assume that the following is configured correctly:
SQL Always On Availability group: AG21. Cluster: FC21, members: SQL21, SQL22. Listener: AGL21.
SQL Failover Cluster Instance. Cluster: FC22, members: SQL23, SQL24. SQL Instance: SQLINST22\INST1.
SCOM Installation
At this point assume the following:
- SCOM is installed on the first mgmt server using the AGL21 for the OpsDB and SQLINST22\INST1 for the DW.
- The 4 SCOM gMSA accounts are provided during setup.
- Web Console role is installed on WEB21 (use mixed auth), no SSL
SSRS
If you are attempting to use the gMSA-Read account for the SSRS service, make sure that you have approved/configured the gMSA account on that SSRS server where it will be used. (see here)
Please note that a gMSA account is NOT officially supported for the SQL report server service for the Data Reader account for SCOM.
BUT it’s obviously possible. Myself and others have implemented it in our own environments and it works great. Proceed with gMSA for the Data Reader account at your own risk. Don’t expect support from Microsoft if you can’t get it to work correctly.
Server Name: SQLRPT21
Install SSRS on SQLRPT21.
Run Report Server Configuration Manager.
Service Account: CONTOSO\gMSA-OMDWRead$
Web Service URL: <default>, no changes
Database:
SQL Server Name: SQLINST22\INST1
Database Name: ReportServer
Mode: Native
Credential: Contoso\gMSA-OMDWREAD$
Web Portal URL: <default>, no changes
Email Settings: <none>
Execution Account:
Use ordinary domain service account for the Execution account (not gMSA). CONTOSO\svcOMRPTExec
Encryption Keys: I backed up the key.
Subscription Settings: CONTOSO\svcOMRPTExec
Scale-out Deployment: SQLRPT21: joined
*see SSRS screenshots below
Execution Account
Cannot be gMSA. Add Execution account login to SSRS database SQL instance (DW SQL clustered instance in this case: ‘SQLINST22\INST1’).
Map Execution account to ReportServer/ReportTemp databases and add RSExec role to both.
Map to Datawarehouse DB and add OpsMgrReader role.
Note: Exec account is allowed “Log on Locally” by default as a domain user.
If you “Deny log on locally”, this will break reporting.
- Install SCOM Reporting Role on SQLRPT21
SQL AOAG Config Tasks
Copy AG logins to other Replicas with DBATools Posh module
SCOM configures all the necessary logins and permissions on the Primary Replica in the AG. However, I must manually copy those logins to the Secondary. I use the DBATools module to make this procedure effortless. I installed the DBATools module directly on my mgmt server from the Gallery.
$AGLSN = 'AGL21\Inst1' #My AG Listener instance
$primaryReplica = Get-DbaAgReplica -SqlInstance $AGLSN | Where Role -eq Primary
$secondaryReplicas = Get-DbaAgReplica -SqlInstance $AGLSN | Where Role -eq Secondary
$LoginsOnPrimary = (Get-DbaLogin -SqlInstance $primaryReplica.Name)
$secondaryReplicas | ForEach-Object {
$LoginsOnSecondary = (Get-DbaLogin -SqlInstance $_.Name)
$diff = $LoginsOnPrimary | Where-Object Name -notin ($LoginsOnSecondary.Name)
if($diff) {
Copy-DbaLogin -Source $primaryReplica.Name -Destination $_.Name -Login $diff.Nane
}
}
At some point I noticed the error described below on my AG node:
Date 9/12/2022 12:11:48 PM Log SQL Server (Current - 9/12/2022 12:05:00 PM) Source Logon Message Database Mirroring login attempt by user 'CONTOSO\gMSA-SCOM-SQL$.' failed with error: 'Connection handshake failed. The login 'CONTOSO\gMSA-SCOM-SQL$' does not have CONNECT permission on the endpoint. State 84.'. [CLIENT: 192.168.XX.XX]
I had to grant the SQL service account permission to connect to the replica.
-- Allow service account to connect to replica
SET NOCOUNT ON
--DECLARE VARIABLES
DECLARE @accountname nvarchar(128)
DECLARE @command1 nvarchar(MAX)
--ENTER DOMAIN ACCOUNT HERE
SET @accountname = 'CONTOSO\gMSA-SCOM-SQL$'
--CREATE LOGIN
SET @command1 = 'USE [master];
IF NOT EXISTS (SELECT [name] FROM sys.server_principals WHERE [name] = ''' + @accountname +''')
CREATE LOGIN ['+@accountname+'] FROM WINDOWS WITH DEFAULT_DATABASE=[master];
'
EXECUTE sp_executesql @command1;
GRANT CONNECT ON ENDPOINT::hadr_endpoint TO [CONTOSO\gMSA-SCOM-SQL$]
GO
Set recovery mode on OperationsManger DB to FULL.
Create full backup.
Add OperationsManager DB to AG, then fully seed.
Perform test failover of OpsMan DB:
- #stop services on mgmt servers
- invoke-command -ComputerName ms21,ms22 -ScriptBlock {Get-Service HealthService,omsdk,cshost | Stop-Service}
- Failover to Secondary using the AG task within SQL Server Mgmt Studio (not Failover Cluster Manager)
- #Start services on mgmt servers
- invoke-command -ComputerName ms21,ms22 -ScriptBlock {Get-Service omsdk,cshost,HealthService | Start-Service}
- Resume synching of AG within SQL Server Mgmt Studio
- Verify “Synchronized” status.
At this point I had installed the SQL management packs. The “Securables” monitor(s) had detected that some securables were not configured correctly. I manually corrected these with the commands below.
YOUR SECURABLES MAY BE DIFFERENT. THIS IS JUST AN EXAMPLE OF HOW I CORRECTED MINE.
SQ21\INST1, SQL22\INST1
No access to the following SQL Server securable(s):
1. Tables:
• msdb.dbo.sysjobschedules
• msdb.dbo.log_shipping_primary_databases
• msdb.dbo.log_shipping_secondary_databases
2. Stored procedures:
• sys.xp_readerrorlog
• msdb.dbo.SQLAGENT_SUSER_SNAME
NOTE: I used a global security group name in the script below (“CONTOSO\grpsec-SCOMSQLMonitoring”). This global security group is added as a Login on my SQL servers and it contains my SQL RunAs account used in the SCOM SQL Discovery and Monitoring profiles. I used the permissions script here to grant the necessary discovery/monitoring permissions to the Login. My customer cannot use the service SID approach so I configured my lab to closely resemble my customer.
USE msdb
--TABLES
GRANT SELECT ON OBJECT::msdb.dbo.sysjobschedules TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GRANT SELECT ON OBJECT::msdb.dbo.log_shipping_primary_databases TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GRANT SELECT ON OBJECT::msdb.dbo.log_shipping_secondary_databases TO [CONTOSO\grpsec-SCOMSQLMonitoring]
--SP
GRANT EXECUTE ON msdb.dbo.SQLAGENT_SUSER_SNAME TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GO
USE [master]
--SP
GRANT EXECUTE ON sys.xp_readerrorlog TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GO
YOUR SECURABLES MAY BE DIFFERENT. THIS IS JUST AN EXAMPLE OF HOW I CORRECTED MINE.
SQLINST22\INST1
No access to the following SQL Server securable(s):
1. Server-level permissions:
• VIEW ANY DEFINITION
2. Tables:
• msdb.dbo.sysjobs_view
• msdb.dbo.sysjobschedules
• msdb.dbo.syscategories
• msdb.dbo.log_shipping_primary_databases
• msdb.dbo.log_shipping_secondary_databases
3. Stored procedures:
• sys.xp_readerrorlog
• msdb.dbo.sp_help_jobactivity
• msdb.dbo.sp_help_job
• msdb.dbo.SQLAGENT_SUSER_SNAME
USE [master]
--SP
GRANT EXECUTE ON sys.xp_readerrorlog TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GO
USE [msdb]
--TABLES
GRANT SELECT ON OBJECT::msdb.dbo.sysjobs_view TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GRANT SELECT ON OBJECT::msdb.dbo.sysjobschedules TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GRANT SELECT ON OBJECT::msdb.dbo.syscategories TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GRANT SELECT ON OBJECT::msdb.dbo.log_shipping_primary_databases TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GRANT SELECT ON OBJECT::msdb.dbo.log_shipping_secondary_databases TO [CONTOSO\grpsec-SCOMSQLMonitoring]
--SP
GRANT EXECUTE ON msdb.dbo.sp_help_jobactivity TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GRANT EXECUTE ON msdb.dbo.sp_help_job TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GRANT EXECUTE ON msdb.dbo.SQLAGENT_SUSER_SNAME TO [CONTOSO\grpsec-SCOMSQLMonitoring]
GO
I also configured maintenance plans for Full, Diff, and TLOG backups of the AOAG (OpsMan) instance. At some point I will get around to adding plans to the DW instance.
Standalone Web Server
Constrained Delegation
WEB21.contoso.com
The WEB21 server must be allowed to delegate credentials to the SDK service on the mgmt servers. This is how you would configure this. I add entries for all mgmt servers.
The Delegation tab for the web console server should look similar to this.
gMSA Constrained Delegation Configuration
Normally when working with Kerberos delegation, you just set the Service Principal Name (SPN) either with setspn.exe command or manually with the attribute editor in Active Directory Users and Computers. Additionally, enabling View > Advanced features in Active Directory Users and Computers adds another way to configure Kerberos delegation from the Delegation tab of a user or a computer account.
However, for standalone and group Managed Service Accounts, the Delegation tab doesn’t appear, even after adding SPNs to these accounts or enabling View > Advanced features.
To configure delegation for these special accounts, you need to set the correct attributes manually. There are two attributes that you need to modify for these accounts:
- userAccountControl defines the type of delegation
- msDS-AllowedToDelegateTo defines where the SPNs for delegation will be added
These attributes can be set in different ways:
- Use PowerShell (the preferred approach by this author)
- Manually update the userAccountControl value
I chose to use PowerShell because that’s how I roll. Here’s what I used to make the changes in PowerShell:
NOTE: modify the gMSA account name as needed, and modify the SPNs section to include your mgmt server accounts.
#my SDK/DAS Service account
$gMSA ='gMSA-OMDAS$'
#TURN ON CONSTRAINED DELEGATION (Use any authentication protocol)
Set-ADAccountControl -Identity $gMSA -TrustedForDelegation $false -TrustedToAuthForDelegation $true -Verbose
#array for spns
$SPNS = `
'MSOMSdkSvc/MS21.CONTOSO.COM' `
,'MSOMSdkSvc/MS21' `
,'MSOMSdkSvc/MS22' `
,'MSOMSdkSvc/MS22.CONTOSO.COM'
# Add mgmt server SDK SPNS to the attribute. Grant Mgmt servers permission to use this account.
Set-ADServiceAccount -Identity $gMSA -Add @{'msDS-AllowedToDelegateTo'= $SPNS } -Verbose
IMPORTANT: You have to allow the web server (frontend resource) access to the gMSA account on the mgmt server SDK (backend resource). Previously I was getting a 403 error until I performed this step.
# Grant Web server access to the 'backend resource'
$FrontendServer = Get-ADComputer web21
Set-ADServiceAccount -Identity $gMSA -PrincipalsAllowedToDelegateToAccount $FrontendServer
# View account properties
Get-ADServiceAccount -Identity $gMSA -Properties *
Also, for reference, in my lab the userAccountControl attribute is as shown below which is a combination/sum of the two permissions shown below which I believe to be correct according to the support doc. This should have been set correctly by running the PowerShell snippet above and there should be no need to modify it manually. That being said, verify that the attribute is correct and fix it if it’s not correct.
References:
- https://docs.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/configure-kerberos-delegation-group-managed-service-accounts
- https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties
I created an alias for my Web Console
Then I added the hostname to the site bindings.
Then I added the HTTP SPNs for the new hostname to the web server object.
Note: If you are simply using the server’s name (not a custom hostname) to access the website, no additional SPNs are needed. The existing HOST SPNs are created automatically and should be sufficient.
IIS Site Bindings
I added an SSL certificate to my IIS server. I first had to create an appropriate Web Server certificate template.
In my lab, my AD server is a certificate authority. The template that I used is a copy of the default Web Server template (available in the Certification Authority tool on my AD server) except I customized the settings as shown below.
I modified the providers as shown below and extended the Validity period to 10 years on the General tab.
I ran these commands on my CA server so that SHA-1 fingerprint would no longer be used; only SHA-256.
I used the MMC Certificates Snap-In on the web console server to request the new Web Server certificate into the Personal store of the Local Computer. You simply right-click on the Personal store to request it.
I also added the Friendly Name on the General tab: “SCOMLAB22”
On the web console server, set the bindings for 443 with the new certificate.
This is how my bindings look upon successful completion.
App Pools
Using ApplicationPoolIdentity is considered a best practice in IIS7 and later versions. Each application pool in IIS runs with its own identity, and the ApplicationPoolIdentity is a dynamically created, unprivileged account that is specific to each application pool. This enhances security by isolating applications from each other and from the system itself.This approach helps minimize the potential impact of security vulnerabilities in one application affecting others. It also reduces the risk associated with using a shared account for multiple application pools. The dynamically created nature of the account means that it is unique to each application pool, enhancing the overall security posture of the server.
-ChatGPT 3.5
Auth
SSRS – Reporting Services Server
These screenshots are numerous and bulky so I put them down here.
If you are attempting to use the gMSA-Read account for the SSRS service, make sure that you have approved/configured the gMSA account on that SSRS server where it will be used.
1) Install the AD tools on the SSRS server with PowerShell:
# Run the following on each server where a gMSA account will be used.
Add-WindowsFeature -Name 'RSAT-AD-Tools' -Verbose
# Restart server
Restart-Computer -Force
2) Configure the account for use on the SSRS server:
# No dollar '$' required on account name here within PowerShell command.
Install-ADServiceAccount 'gMSA-OMDWRead'
#Optionally you can test the service account from the SQL server. This command should return boolean "True".
Test-ADServiceAccount -Identity 'gMSA-OMDWRead'
Here are some screenshots that reveal my SSRS config:
Although the Password field is populated with masked characters, I did not have to provide a password for the gMSA account upon initial configuration. Just leave it blank. The account retrieves its own password from AD. (that’s the whole point of a managed account)
gMSA accounts cannot be used for the Execution Account.
These are all of the notes that I remembered to record. Let me know if you have any specific questions and I’ll do my best to respond in a timely manner. Hope this helps others.
Version History:
2024.01.09 – Improved formatting a little bit.
2022.12.12 – Added a few screenshots.
2022.12.09 – Updated accuracy of SPNs, App Pools, and Constrained Delegation settings. Added SSL certificate template info.
5 Replies to “SCOM 2022 Installation, gMSA, Standalone Web Console Server with Constrained Delegation”
WOW, that is a whole lotta stuff!!
Simple question, hopefully.
I am attempting to install SCOM 202 in my lab. Created the four gMSA accounts (without the $)[edited] at the end.
Attempting to install Reporting Services 2022 on Server 2022.
I enter the domain account for the Service Account: domain\gMSA-Read.
Without the $ it wants a password. With the $ at the end it will let me select Apply, but then I get the following:
The task failed.
System.InvalidOperationException: Cannot start service SQLServerReportingServices on computer ‘ServerName’. —> System.ComponentModel.Win32Exception: The service did not start due to a logon failure
— End of inner exception stack trace —
at System.ServiceProcess.ServiceController.Start(String[] args)
at ReportServicesConfigUI.Panels.ConfigurationPanelWithErrors.StartOrStopServiceTask(Boolean start, String serviceName)
Not a lot of info I know…
Tony
If you are attempting to use the gMSA-Read account for the SSRS service, make sure that you have approved/configured the gMSA account on that SSRS server where it will be used.
1) Install the AD tools on the SSRS server with:
# Run the following on each mgmt server.
Add-WindowsFeature -Name 'RSAT-AD-Tools' -Verbose
# Restart mgmt server
Restart-Computer -Force
2) Configure the account for use on the SSRS server
Install-ADServiceAccount 'gMSA-OMDWRead'
#Optionally you can test the service account from the SQL server. This command should return boolean "True".
Test-ADServiceAccount -Identity 'gMSA-OMDWRead'
I added some guidance to the post here: https://monitoringguys.com/2022/10/06/scom-2022-installation-gmsa-standalone-web-console-server/#ssrsconfig
Hi,
For the Web Console, we are using a GMSA account for the AppPool identity.
What will change in the configuration you provided?
Thanks
First answer this: Why are you using a GMSA account for the AppPool identity?
Using ApplicationPoolIdentity is considered a best practice in IIS7 and later versions. Each application pool in IIS runs with its own identity, and the ApplicationPoolIdentity is a dynamically created, unprivileged account that is specific to each application pool. This enhances security by isolating applications from each other and from the system itself.
This approach helps minimize the potential impact of security vulnerabilities in one application affecting others. It also reduces the risk associated with using a shared account for multiple application pools. The dynamically created nature of the account means that it is unique to each application pool, enhancing the overall security posture of the server.
I’m not the IIS admin, so I’m not sure exactly why, but the standard here state that a GMSA account is require for the ApplicationPoolIdentity.