From 262da6d7d18475ad3a37018d96c152475323382a Mon Sep 17 00:00:00 2001 From: Kevin Cole Date: Thu, 2 Sep 2021 22:48:53 -0600 Subject: [PATCH 1/4] Correct the use of SPServices to run the C2WTS. The SPServices account is not the right account to be running the claims to windows token service as. The C2WTS account requires very special elevated permissions and adding the Services account to local admins will result in warnings displayed in the health analyzer. Unfortunately I don't yet know how to automate configuring of local security policies as it is very low level from what I can google currently... however this is a much better step in the right direction of informing the user they need a specific account with very high risk permissions. --- SP/Automation/AutoSPInstallerInput.xml | 21 +++++++++++++++++- SP/Automation/AutoSPInstallerModule.psm1 | 27 ++++++++++++------------ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/SP/Automation/AutoSPInstallerInput.xml b/SP/Automation/AutoSPInstallerInput.xml index 14851a4..410013e 100644 --- a/SP/Automation/AutoSPInstallerInput.xml +++ b/SP/Automation/AutoSPInstallerInput.xml @@ -153,12 +153,31 @@ - CONTOSO\SP_Services + + + + CONTOSO\SP_Claims + CONTOSO\SP_PortalAppPool diff --git a/SP/Automation/AutoSPInstallerModule.psm1 b/SP/Automation/AutoSPInstallerModule.psm1 index 0aa792b..28fd6d6 100644 --- a/SP/Automation/AutoSPInstallerModule.psm1 +++ b/SP/Automation/AutoSPInstallerModule.psm1 @@ -1759,9 +1759,9 @@ Function GetSecureFarmPassphrase ([xml]$xmlInput) # Func: UpdateProcessIdentity # Desc: Updates the account a specified service runs under to the general app pool account # ==================================================================================== -Function UpdateProcessIdentity ($serviceToUpdate) -{ - $spservice = Get-SPManagedAccountXML $xmlInput -CommonName "spservice" +Function UpdateProcessIdentity ($serviceToUpdate, $managedAccountName = "spservice") +{ + $spservice = Get-SPManagedAccountXML $xmlInput -CommonName $managedAccountName # Managed Account $managedAccountGen = Get-SPManagedAccount | Where-Object {$_.UserName -eq $($spservice.username)} if ($managedAccountGen -eq $null) { Throw " - Managed Account $($spservice.username) not found" } @@ -2489,7 +2489,7 @@ Function ConfigureSandboxedCodeService ([xml]$xmlInput) Try { Write-Host -ForegroundColor White " - Starting Microsoft SharePoint Foundation Sandboxed Code Service..." - UpdateProcessIdentity $sandboxedCodeService + UpdateProcessIdentity -serviceToUpdate $sandboxedCodeService $sandboxedCodeService.Update() $sandboxedCodeService.Provision() If (-not $?) {Throw " - Failed to start Sandboxed Code Service"} @@ -3498,7 +3498,7 @@ Function CreateUserProfileServiceApplication ([xml]$xmlInput) Write-Host -ForegroundColor White " - Deleting existing sync credentials timer job..." $UPSCredentialsJob.Delete() } - UpdateProcessIdentity $profileSyncService + UpdateProcessIdentity -serviceToUpdate $profileSyncService $profileSyncService.Update() Write-Host -ForegroundColor White " - Waiting for User Profile Synchronization Service..." -NoNewline # Provision the User Profile Sync Service @@ -4113,7 +4113,7 @@ Function CreateWebAnalyticsApp ([xml]$xmlInput) $analyticsDataProcessingInstances = Get-SPServiceInstance | Where-Object {$_.GetType().ToString() -eq "Microsoft.Office.Server.WebAnalytics.Administration.WebAnalyticsServiceInstance"} $analyticsDataProcessingInstance = $analyticsDataProcessingInstances | Where-Object {MatchComputerName $_.Server.Address $env:COMPUTERNAME} If (-not $?) { Throw " - Failed to find Analytics Data Processing Service instance" } - UpdateProcessIdentity $analyticsDataProcessingInstance + UpdateProcessIdentity -serviceToUpdate $analyticsDataProcessingInstance $analyticsDataProcessingInstance.Update() Write-Host -ForegroundColor White " - Starting local Analytics Data Processing Service instance..." $analyticsDataProcessingInstance.Provision() @@ -4307,9 +4307,7 @@ Function ConfigureClaimsToWindowsTokenService ([xml]$xmlInput) Write-Host -ForegroundColor White " - Starting $($claimsService.DisplayName)..." if ($xmlInput.Configuration.Farm.Services.ClaimsToWindowsTokenService.UpdateAccount -eq $true) { - UpdateProcessIdentity $claimsService - $claimsService.Update() - # Add C2WTS account (currently the generic service account) to local admins + # Add C2WTS account to local admins $builtinAdminGroup = Get-AdministratorsGroup $adminGroup = ([ADSI]"WinNT://$env:COMPUTERNAME/$builtinAdminGroup,group") # This syntax comes from Ying Li (http://myitforum.com/cs2/blogs/yli628/archive/2007/08/30/powershell-script-to-add-remove-a-domain-user-to-the-local-administrators-group-on-a-remote-machine.aspx) @@ -4322,6 +4320,9 @@ Function ConfigureClaimsToWindowsTokenService ([xml]$xmlInput) Write-Host -ForegroundColor White " - Adding $($managedAccountGen.Username) to local Administrators..." ([ADSI]"WinNT://$env:COMPUTERNAME/$builtinAdminGroup,group").Add("WinNT://$managedAccountDomain/$managedAccountUser") } + + UpdateProcessIdentity -serviceToUpdate $claimsService -managedAccountName $spservice + $claimsService.Update() } $claimsService.Provision() $claimsService | Start-SPServiceInstance @@ -4416,7 +4417,7 @@ Function ConfigureFoundationSearch ([xml]$xmlInput) Try { $foundationSearchService = (Get-SPFarm).Services | Where-Object {$_.Name -eq "SPSearch4"} - UpdateProcessIdentity $foundationSearchService + UpdateProcessIdentity -serviceToUpdate $foundationSearchService } Catch { @@ -4472,7 +4473,7 @@ Function ConfigureTracing ([xml]$xmlInput) } Try { - UpdateProcessIdentity $spTraceV4 + UpdateProcessIdentity -serviceToUpdate $spTraceV4 } Catch { @@ -4586,7 +4587,7 @@ Function ConfigureDistributedCacheService ([xml]$xmlInput) Write-Host -ForegroundColor White " - Applying service account $($spservice.username) to service AppFabricCachingService..." Try { - UpdateProcessIdentity $distributedCachingSvc + UpdateProcessIdentity -serviceToUpdate $distributedCachingSvc } Catch { @@ -6481,7 +6482,7 @@ Function CreateProjectServerServiceApp ([xml]$xmlInput) $projectServiceInstances = (Get-SPFarm).Services | Where-Object {$_.GetType().ToString() -eq $projectService} foreach ($projectServiceInstance in $projectServiceInstances) { - UpdateProcessIdentity $projectServiceInstance + UpdateProcessIdentity -serviceToUpdate $projectServiceInstance } } # Create a Project Server DB (2013 only) From 64c3596c9b3c0f68f9d841b6cb46e8a08dae0024 Mon Sep 17 00:00:00 2001 From: Kevin Cole Date: Thu, 2 Sep 2021 22:52:24 -0600 Subject: [PATCH 2/4] missed using common name, added --- SP/Automation/AutoSPInstallerModule.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SP/Automation/AutoSPInstallerModule.psm1 b/SP/Automation/AutoSPInstallerModule.psm1 index 28fd6d6..ddfd175 100644 --- a/SP/Automation/AutoSPInstallerModule.psm1 +++ b/SP/Automation/AutoSPInstallerModule.psm1 @@ -4312,7 +4312,7 @@ Function ConfigureClaimsToWindowsTokenService ([xml]$xmlInput) $adminGroup = ([ADSI]"WinNT://$env:COMPUTERNAME/$builtinAdminGroup,group") # This syntax comes from Ying Li (http://myitforum.com/cs2/blogs/yli628/archive/2007/08/30/powershell-script-to-add-remove-a-domain-user-to-the-local-administrators-group-on-a-remote-machine.aspx) $localAdmins = $adminGroup.psbase.invoke("Members") | ForEach-Object {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)} - $spservice = Get-SPManagedAccountXML $xmlInput -CommonName "spservice" + $spservice = Get-SPManagedAccountXML $xmlInput -CommonName "spclaims" $managedAccountGen = Get-SPManagedAccount | Where-Object {$_.UserName -eq $($spservice.username)} $managedAccountDomain,$managedAccountUser = $managedAccountGen.UserName -split "\\" If (!($localAdmins -contains $managedAccountUser)) @@ -4321,7 +4321,7 @@ Function ConfigureClaimsToWindowsTokenService ([xml]$xmlInput) ([ADSI]"WinNT://$env:COMPUTERNAME/$builtinAdminGroup,group").Add("WinNT://$managedAccountDomain/$managedAccountUser") } - UpdateProcessIdentity -serviceToUpdate $claimsService -managedAccountName $spservice + UpdateProcessIdentity -serviceToUpdate $claimsService -managedAccountName "spclaims" $claimsService.Update() } $claimsService.Provision() From 246ff49b1ce93a0a5d275a986cd92162868501a4 Mon Sep 17 00:00:00 2001 From: Kevin Cole Date: Fri, 3 Sep 2021 00:00:06 -0600 Subject: [PATCH 3/4] Update MatchComputerName to fix issue with similarly named servers If your WFE is named "NMS-UAT" and your APP is named "NMS-UATAPP" the MatchComputerName will incorrectly return true and cause the service provisioning to try and provision a service from another machine on the current machine. This specifically was happening with the ClaimsToWindowsToken service. --- SP/Automation/AutoSPInstallerModule.psm1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SP/Automation/AutoSPInstallerModule.psm1 b/SP/Automation/AutoSPInstallerModule.psm1 index ddfd175..da07643 100644 --- a/SP/Automation/AutoSPInstallerModule.psm1 +++ b/SP/Automation/AutoSPInstallerModule.psm1 @@ -4330,7 +4330,8 @@ Function ConfigureClaimsToWindowsTokenService ([xml]$xmlInput) } Catch { - Throw " - An error occurred starting $($claimsService.DisplayName)" + Write-Output $_ + Throw " - An error occurred starting $($claimsService.DisplayName)" } #Wait Write-Host -ForegroundColor Cyan " - Waiting for $($claimsService.DisplayName)..." -NoNewline @@ -7721,7 +7722,7 @@ Function Get-SharePointInstall # =================================================================================== Function MatchComputerName ($computersList, $computerName) { - If ($computersList -like "*$computerName*") { Return $true; } + If (",$($computersList)," -like "*,$computerName,*") { Return $true; } foreach ($v in $computersList) { If ($v.Contains("*") -or $v.Contains("#")) { # wildcard processing From fbc8d9ed67f794ba4e26462971f6ecb47b907581 Mon Sep 17 00:00:00 2001 From: Kevin Cole Date: Fri, 3 Sep 2021 00:21:48 -0600 Subject: [PATCH 4/4] $computersList can come in as an array, need to join it with "," --- SP/Automation/AutoSPInstallerModule.psm1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SP/Automation/AutoSPInstallerModule.psm1 b/SP/Automation/AutoSPInstallerModule.psm1 index da07643..86df05c 100644 --- a/SP/Automation/AutoSPInstallerModule.psm1 +++ b/SP/Automation/AutoSPInstallerModule.psm1 @@ -7722,7 +7722,9 @@ Function Get-SharePointInstall # =================================================================================== Function MatchComputerName ($computersList, $computerName) { - If (",$($computersList)," -like "*,$computerName,*") { Return $true; } + $listString = $computersList + if ($computersList -is [array]) { $listString = $computersList -join "," } + If (",$($listString)," -like "*,$($computerName),*") { Return $true; } foreach ($v in $computersList) { If ($v.Contains("*") -or $v.Contains("#")) { # wildcard processing