下载所有 s-s-rS 报告
Posted
技术标签:
【中文标题】下载所有 s-s-rS 报告【英文标题】:Download all s-s-rS reports 【发布时间】:2017-10-17 05:34:37 【问题描述】:我想在一台服务器上获取所有 .rdl 文件的副本。 我可以一次手动下载一份报告,但这很耗时,尤其是这个服务器有大约 1500 份报告。
有什么方法或工具可以让我下载所有 .rdl 文件并复制它们吗?
【问题讨论】:
【参考方案1】:使用 PowerShell 有一个完整且更简单的方法。
此代码将以与报告服务器完全相同的结构导出所有报告内容。查看Github wiki 了解其他选项和命令
#------------------------------------------------------
#Prerequisites
#Install-Module -Name ReportingServicesTools
#------------------------------------------------------
#Lets get security on all folders in a single instance
#------------------------------------------------------
#Declare s-s-rS URI
$sourceRsUri = 'http://ReportServerURL/ReportServer/ReportService2010.asmx?wsdl'
#Declare Proxy so we dont need to connect with every command
$proxy = New-RsWebServiceProxy -ReportServerUri $sourceRsUri
#Output ALL Catalog items to file system
Out-RsFolderContent -Proxy $proxy -RsFolder / -Destination 'C:\s-s-rS_Out' -Recurse
【讨论】:
我希望我能投票 10 次。您刚刚为我节省了几个小时的工作时间。 将 $sourceRsUri 放在单引号中对我不起作用,我必须使用双引号 我得到了Unable to find type [Microsoft.ReportingServicesTools.ConnectionHost]
- 这是在ReportingServicesTools
包中定义的。原来根本原因是从网络路径运行脚本。一旦我从我的 C 盘运行它,它就可以正常工作了。
也适用于 s-s-rS 2017 和 2019!对于 s-s-rS 2017 - $sourceRsUri = 'ReportServerURL/ReportServer/ReportService2017.asmx?wsdl' 对于 s-s-rS 2019 - $sourceRsUri = 'ReportServerURL/ReportServer/ReportService2019.asmx?wsdl'
我遇到了一个奇怪的问题。我指定$sourceRsUri
来查看/ReportService2012.asmx?wsdl
,因为我正在运行s-s-rS 2012,但是在运行脚本时,它一直在查看/ReportService2010.asmx?wsdl
,因此会引发错误。【参考方案2】:
如果您只是出于备份目的或类似目的需要它,这可能会很有用:Where does a published RDL file sit?
来自该线程的相关查询是:
select convert(varchar(max), convert(varbinary(max), content))
from catalog
where content is not null
最初的答案是使用 2005 年,我在 2016 年使用过,所以我想它应该适用于 2008 年和 2012 年。
当我不得不使用它时,我也在查询的路径中添加了,这样我就知道哪个报告是哪个。
CAVEAT:在 SSMS v18 之前,网格结果限制为每个元组 64KB,文本结果限制为每个元组 8,192 个字符。如果您的报告定义大于这些限制,您将无法获得完整的定义。
在 SSMS v18 中,对于 Reports to Grid 和 Results to Text,这些限制已增加到每个元组 2MB。
【讨论】:
【参考方案3】:我创建了这个 powershell 脚本来将它们复制到 ZIP 中。您必须提供 SQL Server 数据库详细信息。
Add-Type -AssemblyName "System.IO.Compression.Filesystem"
$dataSource = "SQLSERVER"
$user = "sa"
$pass = "sqlpassword"
$database = "ReportServer"
$connectionString = "Server=$dataSource;uid=$user; pwd=$pass;Database=$database;Integrated Security=False;"
$tempfolder = "$env:TEMP\Reports"
$zipfile = $PSScriptRoot + '\reports.zip'
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$allreports = $connection.CreateCommand()
$allreports.CommandText = "SELECT ItemID, Path, CASE WHEN Type = 2 THEN '.rdl' ELSE 'rds' END AS Ext FROM Catalog WHERE Type IN(2,5)"
$result = $allreports.ExecuteReader()
$reportable = new-object "System.Data.DataTable"
$reportable.Load($result)
[int]$objects = $reportable.Rows.Count
foreach ($report in $reportable)
$cmd = $connection.CreateCommand()
$cmd.CommandText = "SELECT CAST(CAST(Content AS VARBINARY(MAX)) AS XML) FROM Catalog WHERE ItemID = '" + $report[0] + "'"
$xmldata = [string]$cmd.ExecuteScalar()
$filename = $tempfolder + $report["Path"].Replace('/', '\') + $report["Ext"]
New-Item $filename -Force | Out-Null
Set-Content -Path ($filename) -Value $xmldata -Force
Write-Host "$($objects.ToString()).$($report["Path"])"
$objects -= 1
Write-Host "Compressing to zip file..."
if (Test-Path $zipfile)
Remove-Item $zipfile
[IO.Compression.Zipfile]::CreateFromDirectory($tempfolder, $zipfile)
Write-Host "Removing temporarly data"
Remove-Item -LiteralPath $tempfolder -Force -Recurse
Invoke-Item $zipfile
【讨论】:
这最终帮助了我,而不是接受的答案。非常感谢!【参考方案4】:这是基于 SQL2016/s-s-rS2016 但我认为它应该适用于 2012 年。
SELECT 'http://mysqlServerName/reports/api/v1.0/catalogitems(' + cast(itemid as varchar(256))+ ')/Content/$value' AS url
FROM ReportServer.dbo.Catalog
这将为您提供一个 URL 列表,每个报告一个。
如果上述方法在 s-s-rS 2012 中不起作用,请转到报告管理器,就像您要从那里下载文件一样。检查下载按钮上的 URL,您可能会看到一个 URL,其中嵌入了项目 ID。只需调整上面的代码以匹配该 url 结构。
在此之后如何处理取决于您。 我个人会使用 Chrome 商店here 中提供的名为“Tab Save”的 Chrome 扩展程序。您可以简单地将上面创建的所有 URL 复制并粘贴到其中,然后点击下载按钮...
【讨论】:
【参考方案5】:找到并使用它没有任何问题。无需安装,只需添加我的网址,然后粘贴到 Powershell 中。
https://microsoft-bitools.blogspot.com/2018/09/s-s-rs-snack-download-all-s-s-rs-reports.html
如果链接断开,请查看链接中的代码:
###################################################################################
# Download Reports and DataSources from a s-s-rS server and create the same folder
# structure in the local download folder.
###################################################################################
# Parameters
###################################################################################
$downloadFolder = "c:\temp\s-s-rs\"
$s-s-rsServer = "http://mys-s-rs.westeurope.cloudapp.azure.com"
###################################################################################
# If you can't use integrated security
#$secpasswd = ConvertTo-SecureString "MyPassword!" -AsPlainText -Force
#$mycreds = New-Object System.Management.Automation.PSCredential ("MyUser", $secpasswd)
#$s-s-rsProxy = New-WebServiceProxy -Uri "$($s-s-rsServer)/ReportServer/ReportService2010.asmx?WSDL" -Credential $mycreds
# s-s-rS Webserver call
$s-s-rsProxy = New-WebServiceProxy -Uri "$($s-s-rsServer)/ReportServer/ReportService2010.asmx?WSDL" -UseDefaultCredential
# List everything on the Report Server, recursively, but filter to keep Reports and DataSources
$s-s-rsItems = $s-s-rsProxy.ListChildren("/", $true) | Where-Object $_.TypeName -eq "DataSource" -or $_.TypeName -eq "Report"
# Loop through reports and data sources
Foreach($s-s-rsItem in $s-s-rsItems)
# Determine extension for Reports and DataSources
if ($s-s-rsItem.TypeName -eq "Report")
$extension = ".rdl"
else
$extension = ".rds"
# Write path to screen for debug purposes
Write-Host "Downloading $($s-s-rsItem.Path)$($extension)";
# Create download folder if it doesn't exist (concatenate: "c:\temp\s-s-rs\" and "/s-s-rSFolder/")
$downloadFolderSub = $downloadFolder.Trim('\') + $s-s-rsItem.Path.Replace($s-s-rsItem.Name,"").Replace("/","\").Trim()
New-Item -ItemType Directory -Path $downloadFolderSub -Force > $null
# Get s-s-rS file bytes in a variable
$s-s-rsFile = New-Object System.Xml.XmlDocument
[byte[]] $s-s-rsDefinition = $null
$s-s-rsDefinition = $s-s-rsProxy.GetItemDefinition($s-s-rsItem.Path)
# Download the actual bytes
[System.IO.MemoryStream] $memoryStream = New-Object System.IO.MemoryStream(@(,$s-s-rsDefinition))
$s-s-rsFile.Load($memoryStream)
$fullDataSourceFileName = $downloadFolderSub + "\" + $s-s-rsItem.Name + $extension;
$s-s-rsFile.Save($fullDataSourceFileName);
【讨论】:
【参考方案6】:我尝试了这个脚本的几种排列,并不断收到“无法创建代理连接”错误。这是“应该”工作的一个:
#------------------------------------------------------
#Prerequisites
#Install-Module -Name ReportingServicesTools
#------------------------------------------------------
#Lets get security on all folders in a single instance
#------------------------------------------------------
#Declare s-s-rS URI
$sourceRsUri = "http://hqmnbi:80/ReportServer_SQL08/ReportService2010.asmx?wsdl"
#Declare Proxy so we dont need to connect with every command
$proxy = New-RsWebServiceProxy -ReportServerUri $sourceRsUri
#Output ALL Catalog items to file system
Out-RsFolderContent -Proxy $proxy -RsFolder / -Destination 'C:\Users\arobinson\source\Workspaces\EDW\MAIN\s-s-rS\HQMNBI' -Recurse
这是我得到的错误:
无法建立到 http://hqmnbi/ReportServer_SQL08/ReportService2010.asmx 的代理连接:HTML 文档不包含 Web 服务发现信息。 在 C:\Program Files\WindowsPowerShell\Modules\ReportingServicesTools\0.0.6.6\Functions\Utilities\New-RsWebServiceProxy.ps1:136 char:9
throw (New-Object System.Exception("Failed to establish proxy ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : OperationStopped: (:) [], 异常
FullyQualifiedErrorId:无法建立到 http://hqmnbi/ReportServer_SQL08/ReportService2010.asmx 的代理连接:
HTML 文档不包含 Web 服务发现信息。
我已经尝试了带有 http:// 的 URI,但没有尝试包含端口号。等等。仍然无法让它真正起作用。我们还有另外两个 s-s-rS 实例,我可以毫无问题地运行它。
【讨论】:
以上是关于下载所有 s-s-rS 报告的主要内容,如果未能解决你的问题,请参考以下文章