RSConfig генерирует строку подключения Dsn не работает - PullRequest
13 голосов
/ 06 мая 2019

TL; DR .

Действия по воспроизведению, создайте резервную копию вашего C:\Program Files\Microsoft SQL Server\MSRS13.SSRS\Reporting Services\ReportServer\RsReportServer.config

Запустите эту команду, чтобы обновить строку подключения в конфигурации SSRS:

C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn>rsconfig -c -s <ServerName> -i <instanceNameIfNotDefault> -d "reportserver$ssrs" -a SQL -u sa -p "YourSAPassword" -t

Теперь перейдите на веб-сайт SSRS.и это не работает!Чтобы исправить это, либо восстановите ваш конфигурационный файл, либо запустите средство SSRS GUI, и оно работает!

Как работает утилита RsConfig?


Фон
После того, как я установил SSRS на сервере Windows 2016 и восстановил 2 базы данных, мне нужно изменить строку подключения в файле конфигурации SSRS, указав имя / экземпляр нового сервера SQL.

enter image description here

Проблема
Когда я пытаюсь изменить зашифрованную строку подключения в файле C:\Program Files\Microsoft SQL Server\MSRS13.SSRS\Reporting Services\ReportServer\RsReportServer.config с помощью утилиты RSConfig:

C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn>rsconfig -c -s Server0012 -i SSRS -d "reportserver$ssrs" -a SQL -u sa -p "P@ssw0rd!" -t

Изменяет DsnСтрока подключения в RsReportServer.config.

1034 * До: 1037 * AQAAANCMnd8BFdERjHoAwE / Cl + sBAAAAE + ТСК / 4Vs0a0fdH0tCY8kgQAAAAiAAAAUgBlAHAAbwByAHQAaQBuAGcAIABTAGUAcgB2AGUAcgAAABBmAAAAAQAAIAAAAC2DBxZFsfVB16r0e3 ...... * 1039 * После того, как: 1042 *AQAAANCMnd8BFdERjHoAwE / Cl + sBAAAAE + ТСК / 4Vs0a0fdH0tCY8kgQAAAAiAAAAUgBlAHAAbwByAHQAaQBuAGcAIABTAGUAcgB2AGUAcgAAABBmAAAAAQAAIAAAAO2nOjFDJMo ........ * 1044 * Однако после этого изменения, просматривающих результатов SSRS Сайта в ошибке:

отчетаСервер не может подключиться к своей базе данных.Убедитесь, что база данных работает и доступна.Вы также можете проверить подробности в журнале трассировки сервера отчетов.

enter image description here

Если я запускаю средство настройки служб отчетов SQL (GUI)) и измените просмотр строки подключения Dsn на веб-сайт SSRS!

enter image description here

enter image description here

Очевидно, что это меняет Dsn, но я не могу понять, что еще он делает, пока работает инструмент с графическим интерфейсом.Я использовал ProcessMonitor и видел, что инструмент с графическим интерфейсом НЕ использует утилиту RSConfig.exe, он использует сам RsConfigTool.exe!Поэтому я даже не могу захватить аргументы командной строки о том, какой должна быть строка команды / соединения.Кроме того, каждый раз, когда мы меняем строку подключения, генерируется новая случайная строка, так что не знаете, как сделать сравнение фактического с ожидаемым.

Я сделал WinDiff ключей реестра и, кроме некоторых зашифрованных шестнадцатеричных различий, ничего не выделялось.

Я запускаю SQLProfiler, и в моем скрипте PowerShell я эмулировал несколько грантов, например:

$sqls += @"
USE [ReportServer`$SSRSTempDB]
if not exists (select * from sysusers where issqlrole = 1 and name = 'RSExecRole')
BEGIN
 EXEC sp_addrole 'RSExecRole'
END;
GO

Моя догадка - это знак $ в имени базы данных SQL и@ в «вымышленном / смоделированном» пароле не экранируются при запуске команд, например:

$MachineName = "server0012"
$instanceName = "SSRS"
$saPassword = "P@ssw0rd!"

$rsConfigPath = "C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\rsconfig.exe"
$setupArgs = -join('-c -s "', $MachineName,'" -i "', $instanceName,'" -d ','"ReportServer`$SSRS" -t -a SQL -u "sa" -p "', $saPassword,"""")

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process
Write-Host $rsConfigPath $setupArgs
$args = $setupArgs.Split(" ")
& "$rsConfigPath" $args

Restart-Service -Force "SQL Server ($instanceName)"

Когда я запускаю эти ванильные команды в командной строке (не нужно экранировать символы PowerShell):

rsconfig -c -s Server0012 -i SSRS -d "reportserver$ssrs" -a SQL -u sa -p "P@ssw0rd!"

Изменяет строку подключения Dsn, но при переходе на веб-сайт SSRS выдает ту же ошибку (см. Выше).

Как узнать, что еще делает RsConfigTool.exe при изменении текущей базы данных сервера отчетов?Или какие-то догадки, почему строка подключения, сгенерированная с помощью утилиты RSConfig, вышла из строя - я пробовал много разных комбинаций, кажется, что только RSConfigTool действительно может это сделать?

Примечание 1:
I'mСценарий это все как проект DevOps, и мы запекаем эти изображения с упаковщиком, так что ничего нельзя сделать вручную.

Примечание 2:
Компьютер присоединен к домену и переименован после установки SQL.Так что, используя файл Configuration.ini, я не думаю, что он будет работать.

Ответы [ 2 ]

2 голосов
/ 30 мая 2019

Хитрость в том, что вам нужно использовать команду Powershell Invoke-Expression, имя сервера должно включать имя экземпляра без кавычек server \ instance, и вам НЕОБХОДИМО экранировать знак $ в команде RsConfig.exe: -d ','"reportserver<tilda>$ssrs"'

= ` Клавиша тильды, которая экранирует знак $, см. В скрипте ниже.

Если вы не используете Invoke-Expression и не используете знак $, имя базы данных называется ReportServer , а не ReportServer $ SSRS

enter image description here

Вы можете увидеть это в журналах SSRS:

библиотека! WindowsService_1! 30c! 05/17 / 2019-03: 56: 29 :: e ОШИБКА: Бросок Microsoft.ReportingServices.Library.ReportServerDatabaseUnavailableException: , Microsoft.ReportingServices.Library.ReportServerDatabaseUnavailableException: Сервер отчетов не может открыть соединение с сервером отчетов база данных. Подключение к базе данных требуется для всех запросов и обработка. ---> System.Data.SqlClient.SqlException: A При установке произошла ошибка, связанная с сетью или экземпляром соединение с SQL Server. Сервер не был найден или не был доступны. Убедитесь, что имя экземпляра правильное и что SQL Сервер настроен для разрешения удаленных подключений. (поставщик: Именован Pipes Provider, ошибка: 40 - Не удалось открыть соединение с SQL Server)

Вот скрипт, который я использую для исправления некорректной установки SQL на сервере, который был переименован:

Param(
    [parameter(mandatory=$true,helpmessage="New Machine Name")]
    [string]$MachineName,

    [parameter(mandatory=$false,helpmessage="SQL Instance Name")]
    [string]$instanceName = "SSRS",

    [parameter(mandatory=$false,helpmessage="SQL SA Password")]
    [string]$saPassword = "P@ssword1"  #this is encrypted IRL
)


#1. Start the logging
Start-Transcript -Path "C:\temp\rename-ssrs-computer.txt"

#2. Change the SQL Server's name
Write-Host "Change the SQL Server Instance Name to $MachineName"


$moduleName = "SqlServer"
Import-Module $moduleName -Verbose

$sql = 'select @@SERVERNAME'
$serverNameQry = Invoke-SqlCmd -Serverinstance ".\$instanceName" -Query $sql -username "sa" -password $saPassword  -querytimeout ([int]::MaxValue)
$serverName = $serverNameQry.Column1

$sql = -join('sp_dropserver ''', $serverName,'''
GO
sp_addserver ''', $MachineName, "\", $instanceName,''',''local''
GO
')
Invoke-SqlCmd -Serverinstance ".\$instanceName" -Query $sql -username "sa" -password $saPassword  -querytimeout ([int]::MaxValue)

#3. Change the SSRS database permissions
$sqls = @()
$sqls += @"
USE master

DECLARE @AccountName nvarchar(260)
SET @AccountName = SUSER_SNAME(0x010100000000000514000000)
if not exists (select name from syslogins where name = @AccountName and hasaccess = 1 and isntname = 1)
BEGIN
EXEC sp_grantlogin @AccountName
END;
GO
"@

#..... all the SQL Profile trace outputs...#

Foreach ($sql in $sqls)
{
  Invoke-SqlCmd -Serverinstance ".\$instanceName" -Query $sql -username "sa" -password $saPassword  -querytimeout ([int]::MaxValue)
}

#4. Change all the registry key values with the AMI Original Computer Name
Write-Host "Change the SQL Server Name in the Registry to $MachineName"

$txt = -join('Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\130\Machines]
"OriginalMachineName"="',$MachineName,'"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server\90\Machines]
"OriginalMachineName"="',$MachineName,'"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server\140\Machines]
"OriginalMachineName"="',$MachineName,'"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server\130\Machines]
"OriginalMachineName"="',$MachineName,'"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Services\SSIS Server]
"GroupPrefix"="SQLServerDTSUser$',$MachineName,'"
"LName"=""
"Name"="MsDtsServer"
"Type"=dword:00000004

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server\Services\SSIS Server]
"GroupPrefix"="SQLServerDTSUser$',$MachineName,'"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Services\Report Server]
"Name"="ReportServer"
"LName"="ReportServer$"
"Type"=dword:00000006
"GroupPrefix"="SQLServerReportServerUser$',$MachineName,'$"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server\Services\Report Server]
"Name"="ReportServer"
"LName"="ReportServer$"
"Type"=dword:00000006
"GroupPrefix"="SQLServerReportServerUser$',$MachineName,'$"'

)

Add-Content "C:\temp\output.reg" $txt
regedit /s "C:\temp\output.reg"


#5. Set the encrypted connection string DONT CHANGE THIS!!!
$rsConfigPath = "C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\"
$setupArgs = -join('-c -s ', $MachineName, '\' , $instanceName,' -i ', $instanceName,' -d ','"reportserver`$ssrs"', ' -t -a SQL -u sa -p "', $saPassword,'"')
Write-Host "Setup args for RSConfig $rsConfigPath $setupArgs"
Write-Host "Running RSConfig"
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process
Write-Host $rsConfigPath $setupArgs

Set-Location "$rsConfigPath"
Invoke-Expression $("rsconfig.exe " + $setupArgs) 

Write-Host "RSConfig Dsn complete, new Connection string under Dsn saved to rsconfig.config file."


#6. Restart the SQL Service
Write-Host "Restarting $instanceName"
Restart-Service -Force "SQL Server ($instanceName)"
Write-Host "Restarted $instanceName"


#7. Set regional format (date/time etc.) to English (Australia) - this applies to all users 
Import-Module International 
Set-Culture en-AU 
# Check language list for non-US input languages, exit if found 
$currentlist = Get-WinUserLanguageList 
$currentlist | ForEach-Object {if(($.LanguageTag -ne "en-AU") -and ($.LanguageTag -ne "en-US")){exit}} 
# Set the language list for the user, forcing English (Australia) to be the only language 
Set-WinUserLanguageList en-AU -Force 
Set-TimeZone -Name "AUS Eastern Standard Time"


# Lastly Stop the transcript (before the PC gets rebooted by the calling script).
Stop-Transcript
1 голос
/ 15 мая 2019

Проблема не в RsConfigTool.exe. Это работает и действительно корректно изменяет строку подключения.

Проблема сводится к одиночным кавычкам против двойных кавычек и наличию знака $ в названии

Из документов :

Когда вы заключаете строку в двойные кавычки (двойные кавычки строка), имена переменных, которым предшествует знак доллара ($) заменяется значением переменной перед передачей строки в команда для обработки.

Мы видим это, когда пытаемся вывести имя базы данных:

PS C:\> Write-Output "ReportServer$SSRS"
ReportServer

Как мы видим, он возвращает «ReportServer», а затем содержимое переменной $SSRS (которая пуста).

Чтобы доказать это, если мы создадим и установим значение для переменной $SSRS:

PS C:\> $SSRS = "SomethingElse"
PS C:\> Write-Output "ReportServer$SSRS"
ReportServerSomethingElse

Мы получаем "SomethingElse" ;-). Но если мы заключим его в одинарные кавычки, он не заменит переменную:

PS C:\> Write-Output 'ReportServer$SSRS'
ReportServer$SSRS

Итак, исправление заключается в том, что при вызове инструмента PowerShell из RsConfigTool.exe просто замените двойные кавычки одинарными:

rsconfig -c -s Server0012 -i SSRS -d 'reportserver$ssrs' -a SQL -u sa -p 'P@ssw0rd!' -t
...