简体   繁体   English

RSConfig生成Dsn连接字符串不起作用

[英]RSConfig generates a Dsn Connection String doesn't work

TL;DR . TL; DR

Repro steps, take a backup of your C:\\Program Files\\Microsoft SQL Server\\MSRS13.SSRS\\Reporting Services\\ReportServer\\RsReportServer.config Repro步骤,备份您的C:\\Program Files\\Microsoft SQL Server\\MSRS13.SSRS\\Reporting Services\\ReportServer\\RsReportServer.config

Run this command to update the connection string in SSRS's 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

Now browse to the SSRS website and it doesn't work! 现在浏览到SSRS网站,它不起作用! To fix it either restore your config file or run through the SSRS GUI tool and it works! 要修复它,请恢复配置文件或运行SSRS GUI工具,它可以正常工作!

How does the RsConfig utility work? RsConfig实用程序如何工作?


Background 背景
After I install SSRS on an Windows 2016 Server and restore the 2 databases I need to change the Connection String in SSRS configuration file to point to the new SQL server name/instance. 在Windows 2016 Server上安装SSRS并恢复2个数据库后,我需要更改SSRS配置文件中的连接字符串以指向新的SQL Server名称/实例。

在此输入图像描述

Problem 问题
When I try to change the encrypted Connection String in C:\\Program Files\\Microsoft SQL Server\\MSRS13.SSRS\\Reporting Services\\ReportServer\\RsReportServer.config file using the RSConfig utility: 当我尝试使用RSConfig实用程序更改C:\\Program Files\\Microsoft SQL Server\\MSRS13.SSRS\\Reporting Services\\ReportServer\\RsReportServer.config文件中的加密连接字符串时:

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

It changes the Dsn Connection String in the RsReportServer.config. 它更改RsReportServer.config中的Dsn连接字符串。

Before: <Dsn>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAE+tJc/4Vs0a0fdH0tCY8kgQAAAAiAAAAUgBlAHAAbwByAHQAaQBuAGcAIABTAGUAcgB2AGUAcgAAABBmAAAAAQAAIAAAAC2DBxZFsfVB16r0e3...... * 之前: <Dsn> AQAAANCMnd8BFdERjHoAwE / Cl + sBAAAAE + tJc / 4Vs0a0fdH0tCY8kgQAAAAiAAAAUgBlAHAAbwByAHQAaQBuAGcAIABTAGUAcgB2AGUAcgAAABBmAAAAAQAAAAAAC2DBxZFsfVB16r0e3 ...... *

After: <Dsn>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAE+tJc/4Vs0a0fdH0tCY8kgQAAAAiAAAAUgBlAHAAbwByAHQAaQBuAGcAIABTAGUAcgB2AGUAcgAAABBmAAAAAQAAIAAAAO2nOjFDJMo........ * 之后: <Dsn> AQAAANCMnd8BFdERjHoAwE / Cl + sBAAAAE + tJc / 4Vs0a0fdH0tCY8kgQAAAAiAAAAUgBlAHAAbwByAHQAaQBuAGcAIABTAGUAcgB2AGAAcgAAABBmAAAAAQAAAAAAAAnAnAnAnFnJMo ........ *

However after this change, browsing to the SSRS Website results in the error: 但是,在此更改后,浏览到SSRS网站会导致错误:

The report server can't connect to its database. 报表服务器无法连接到其数据库。 Make sure the database is running and accessible. 确保数据库正在运行且可访问。 You can also check the report server trace log for details. 您还可以检查报表服务器跟踪日志以获取详细信息。

在此输入图像描述

If I run the SQL Reporting Services Configuration Tool (GUI) and change the Dsn Connection String browsing to the SSRS Website works! 如果我运行SQL Reporting Services配置工具(GUI)并更改Dsn连接字符串浏览到SSRS网站工作!

在此输入图像描述

在此输入图像描述

Obviously it changes the Dsn but I can't work out what else it does whilst the GUI tool is running. 显然它改变了Dsn,但我无法弄清楚它在GUI工具运行时做了什么。 I've used ProcessMonitor and I've seen that the GUI tool does NOT use RSConfig.exe utility, it uses itself RsConfigTool.exe! 我用的ProcessMonitor和我见过的GUI工具使用RSConfig.exe工具,它使用自身RsConfigTool.exe! So I can't even capture command-line arguments of what the actual command/connection string should be. 所以我甚至无法捕获实际命令/连接字符串应该是什么的命令行参数。 Also each time we change the connection string a new random one is generated so not sure how to do comparison's of actual vs expected. 此外,每次我们更改连接字符串时,都会生成一个新的随机字符串,因此不确定如何进行实际与预期的比较。

I did a WinDiff of Registry keys and apart from some encrypted hexadecimal diffs, nothing stood out. 我做了一个WinDiff的注册表键,除了一些加密的十六进制差异,没有什么突出。

I run SQLProfiler and there were a bunch of grants that I have emulated in my PowerShell script, eg: 我运行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

My hunch is the $ sign in the SQL Database Name and the @ in the "made up/simulated" password are not getting escaped when I run the commands, eg: 我的预感是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)"

When I run these vanilla commands in Command Prompt (no need to escape PowerShell characters): 当我在命令提示符中运行这些vanilla命令时(无需转义PowerShell字符):

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

It changes the Dsn Connection String but browsing to SSRS Website gives same error (above). 它更改了Dsn连接字符串,但浏览到SSRS网站会出现同样的错误(上图)。

How can I find out what else RsConfigTool.exe does when changing the Current Report Server Database? 如何在更改当前报表服务器数据库时找出RsConfigTool.exe的其他内容? Or any guesses why the Connection String generated using the RSConfig Utility is out of whack - I've tried many different combinations, seems like only the RSConfigTool can actually do it? 或者任何猜测为什么使用RSConfig实用程序生成的连接字符串是不成功的 - 我尝试了很多不同的组合,似乎只有RSConfigTool才能真正做到这一点?

Note 1: 注1:
I'm scripting this all up as a DevOps project and we are baking these images with packer, so nothing can be done manually. 我正在编写这个作为DevOps项目的脚本,我们正在用打包器烘焙这些图像,因此无法手动完成任何操作。

Note 2: 笔记2:
The Machine is joined to the domain and renamed after SQL installed. 机器加入域并在安装SQL后重命名。 So using a Configuration.ini file I don't think will work. 所以使用Configuration.ini文件我认为不会起作用。

The trick is you need to use the Powershell Invoke-Expression command, the server name has to include the instance name without quotes server\\instance, and you DO need to escape the $ sign in the RsConfig.exe command: -d ','"reportserver<tilda>$ssrs"' 诀窍是您需要使用Powershell Invoke-Expression命令,服务器名称必须包含实例名称而不包含引号server \\ instance,并且您需要转义RsConfig.exe命令中的$符号: -d ','"reportserver<tilda>$ssrs"'

<tilda> = ` The tilda key that escapes the $ sign, see in script below. <tilda> = `逃脱$符号的tilda键,请参阅下面的脚本。

If you don't use Invoke-Expression and escape the $ sign the DatabaseName is called ReportServer not ReportServer$SSRS 如果不使用Invoke-Expression并转义$ sign,则DatabaseName称为ReportServer而不是ReportServer $ SSRS

在此输入图像描述

You can see this in the SSRS Logs: 您可以在SSRS日志中看到:

library!WindowsService_1!30c!05/17/2019-03:56:29:: e ERROR: Throwing Microsoft.ReportingServices.Library.ReportServerDatabaseUnavailableException: , Microsoft.ReportingServices.Library.ReportServerDatabaseUnavailableException: The report server cannot open a connection to the report server database. 库!WindowsService_1!30c!05/17 / 2019-03:56:29 :: e错误:抛出Microsoft.ReportingServices.Library.ReportServerDatabaseUnavailableException:,Microsoft.ReportingServices.Library.ReportServerDatabaseUnavailableException:报表服务器无法打开与报表的连接服务器数据库 A connection to the database is required for all requests and processing. 所有请求和处理都需要与数据库的连接。 ---> System.Data.SqlClient.SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. ---> System.Data.SqlClient.SqlException:建立与SQL Server的连接时发生与网络相关或特定于实例的错误。 The server was not found or was not accessible. 服务器未找到或无法访问。 Verify that the instance name is correct and that SQL Server is configured to allow remote connections. 验证实例名称是否正确,以及SQL Server是否配置为允许远程连接。 (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) (提供者:命名管道提供程序,错误:40 - 无法打开与SQL Server的连接)

Here is the script I use to fix a broken SQL install on a server that's been renamed: 这是我用于在已重命名的服务器上修复损坏的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

The issue is not with the RsConfigTool.exe. 问题不在于RsConfigTool.exe。 It works, and indeed changes the connection string properly. 它工作正常,并确实正确地更改了连接字符串。

The issue simply boils down to single quotes vs. double quotes and having a $ sign in the name. 问题简单归结为单引号与双引号以及名称中的$符号。

From the docs : 来自文档

When you enclose a string in double quotation marks (a double-quoted string), variable names that are preceded by a dollar sign ($) are replaced with the variable's value before the string is passed to the command for processing. 将字符串括在双引号(双引号字符串)中时,在将字符串传递给命令进行处理之前,将以美元符号($)开头的变量名替换为变量的值。

We can see this when we try to output the database name: 当我们尝试输出数据库名称时,我们可以看到这一点:

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

As we can see, it returns "ReportServer" and then the contents of the $SSRS variable (which is empty). 我们可以看到,它返回“ReportServer”,然后返回$SSRS变量的内容 (为空)。

To prove this, if we create and set a value to the $SSRS variable: 为了证明这一点,如果我们为$SSRS变量创建并设置一个值:

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

We get "SomethingElse" ;-). 我们得到“SomethingElse”;-)。 But if we enclose it in single quotes, it does not do a variable replacement: 但是如果我们用单引号将它括起来,它就不会做变量替换:

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

So, the fix, is when calling the RsConfigTool.exe tool from PowerShell, simply replace the double quotes with single quotes: 因此,修复是在从PowerShell调用RsConfigTool.exe工具时,只需用单引号替换双引号:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ServerConnection 不适用于连接字符串 - ServerConnection doesn't work with a connection string 成员资格角色提供程序不能与自定义连接字符串一起使用? - Membership Role Provider doesn't work with custom connection string? ASP,DSN-Less连接,连接字符串语法给出未找到数据源名称的错误 - ASP, DSN-Less connection, connection string syntax gives Data source name not found error Postgresql,tsquery 不适用于部分字符串 - Postgresql, tsquery doesn't work with part of string Reader循环不适用于字符串中的参数 - Reader loop doesn't work with parameter in string SQL中的字符串连接不起作用 - String concatenation in SQL doesn't work 关于 dsn 字符串的查询 - Query regarding dsn string 与mysql的连接未关闭($ conn-&gt; close似乎不起作用) - Connection to mysql is not closing ($conn->close doesn't seem to work) 通过dsn错误进行ODBC连接 - ODBC connection through dsn error 行var connection = new ActiveXObject(“ ADODB.Connection”)是什么? 是什么意思,为什么不起作用? - what does the line var connection = new ActiveXObject(“ADODB.Connection”); mean and why doesn't it work?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM