function Set-SMSvcHostSids { <# .SYNOPSIS Checks to see if the SMSvcHost.exe.config contains permissions for SIDs for the DBMS and Micro accounts. Adds them and the containing xml nodes if not. #> [CmdletBinding()] param( ) $logLead = (Get-LogLeadName); $configFilePath = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SMSvcHost.exe.config" $dbmsAccountName = Get-AppSetting "DatabaseMicroServiceAccount" $dbmsSid = $null if($null -ne $dbmsAccountName) { $dbmsSid = Get-SIDFromUserName $dbmsAccountName } else { throw ("$logLead : Machine.config must have an appsetting value for the dbms account.") } $microAccountName = Get-AppSetting "NonDatabaseMicroServiceAccount" $microSid = $null if($null -ne $microAccountName) { $microSid = Get-SIDFromUserName $microAccountName } else { throw ("$logLead : Machine.config must have an appsetting value for the micro account.") } try { [Xml]$smSvcHostConfig = Read-XMLFile $configFilePath -ErrorAction SilentlyContinue if ([String]::IsNullOrEmpty($smSvcHostConfig)) { throw ("$logLead : The SMSvcHost.exe.config config file could not be found") } } catch { throw ("$logLead : The SMSvcHost.exe.config config file could not be read or is invalid.") } $configFileIsDirty = $false; $xmlBlock = [xml]" " $xmlNodeNames = @( "system.serviceModel.activation", "net.tcp", "allowAccounts", "add" ) $nullNodeName = $null; $knownParentNode = "configuration"; foreach ($xmlNodeName in $xmlNodeNames) { if($smSvcHostConfig.SelectNodes("//$xmlNodeName").Count -eq 0) { $nullNodeName = $xmlNodeName break; } else { $knownParentNode = $xmlNodeName } } if(($null -eq $nullNodeName) -or ($nullNodeName -eq "add")) { $dbmsNode = $smSvcHostConfig.SelectNodes("//add[@securityIdentifier='$dbmsSid']") # test for existing sids # just 2 potential SIDs here, so not bothering with complex loop logic. if($null -eq $dbmsNode -or $dbmsNode.Count -eq 0 ) { Write-Verbose ("$logLead : Dbms SID does not exist. New SIDs being added.") $configFileIsDirty = $true; $newNode = [xml]""; $smSvcHostConfig.SelectSingleNode("//allowAccounts").AppendChild($smSvcHostConfig.ImportNode($newNode.add, $true)) } $microNode = $smSvcHostConfig.SelectNodes("//add[@securityIdentifier='$microSid']") if($null -eq $microNode -or $microNode.Count -eq 0 ) { Write-Verbose ("$logLead : Micro SID does not exist. New SIDs being added.") $configFileIsDirty = $true; $newNode = [xml]""; $smSvcHostConfig.SelectSingleNode("//allowAccounts").AppendChild($smSvcHostConfig.ImportNode($newNode.add, $true)) } } else { Write-Verbose ("$logLead : $nullNodeName does not exist. New SIDs being added.") $configFileIsDirty = $true # This could be one line, but it's far more readable split out like this. $newNodes = $xmlBlock.SelectSingleNode("//$nullNodeName"); $importedNodes = $smSvcHostConfig.ImportNode($newNodes, $true); $smSvcHostConfig.SelectSingleNode("//$knownParentNode").AppendChild($importedNodes) } if ($configFileIsDirty) { Write-Host ("$logLead : Saving the Modified The SMSvcHost.exe.config Configuration File" -f $nrConfigPath) $utfNoBOM = New-Object System.Text.UTF8Encoding($false) try { Save-XMLFile $configFilePath $smSvcHostConfig.OuterXml.Replace('xmlns="" ', [String]::Empty) $utfNoBOM } catch { $ErrorMessage = $_.Exception.Message Write-Warning ("$logLead : Saving file failed.") Write-Warning ("$logLead : $ErrorMessage") return } } else { Write-Host "$logLead : No Changes Required to The SMSvcHost.exe.config" } }