下载所有 SSRS 报告

问题描述 投票:0回答:9

我想获取一台服务器中所有 .rdl 文件的副本。 我可以一次手动下载一份报告,但这很耗时,尤其是该服务器有大约 1500 个报告。

有什么方法或工具可以让我下载所有 .rdl 文件并获取它们的副本吗?

sql-server reporting-services ssrs-2008 ssrs-2012 ssrs-2019
9个回答
81
投票

有一种完整且更简单的方法可以使用 PowerShell 来执行此操作。

此代码将以与报表服务器完全相同的结构导出所有报表内容。查看 Github wiki 了解其他选项和命令

#------------------------------------------------------
#Prerequisites
#Install-Module -Name ReportingServicesTools
#------------------------------------------------------

#Lets get security on all folders in a single instance
#------------------------------------------------------
#Declare SSRS 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:\SSRS_Out' -Recurse

8
投票

我创建了这个 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

3
投票

发现并使用它没有任何问题。无需安装,只需添加我的网址,然后粘贴到 Powershell 中。

https://microsoft-bitools.blogspot.com/2018/09/ssrs-snack-download-all-ssrs-reports.html

以防链接中断,以下是链接中的代码:

###################################################################################
# Download Reports and DataSources from a SSRS server and create the same folder
# structure in the local download folder.
###################################################################################
# Parameters
###################################################################################
$downloadFolder = "c:\temp\ssrs\"
$ssrsServer = "http://myssrs.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)
#$ssrsProxy = New-WebServiceProxy -Uri "$($ssrsServer)/ReportServer/ReportService2010.asmx?WSDL" -Credential $mycreds
 
# SSRS Webserver call
$ssrsProxy = New-WebServiceProxy -Uri "$($ssrsServer)/ReportServer/ReportService2010.asmx?WSDL" -UseDefaultCredential
 
# List everything on the Report Server, recursively, but filter to keep Reports and DataSources
$ssrsItems = $ssrsProxy.ListChildren("/", $true) | Where-Object {$_.TypeName -eq "DataSource" -or $_.TypeName -eq "Report"}
 
# Loop through reports and data sources
Foreach($ssrsItem in $ssrsItems)
{
    # Determine extension for Reports and DataSources
    if ($ssrsItem.TypeName -eq "Report")
    {
        $extension = ".rdl"
    }
    else
    {
        $extension = ".rds"
    }
     
    # Write path to screen for debug purposes
    Write-Host "Downloading $($ssrsItem.Path)$($extension)";
 
    # Create download folder if it doesn't exist (concatenate: "c:\temp\ssrs\" and "/SSRSFolder/")
    $downloadFolderSub = $downloadFolder.Trim('\') + $ssrsItem.Path.Replace($ssrsItem.Name,"").Replace("/","\").Trim() 
    New-Item -ItemType Directory -Path $downloadFolderSub -Force > $null
 
    # Get SSRS file bytes in a variable
    $ssrsFile = New-Object System.Xml.XmlDocument
    [byte[]] $ssrsDefinition = $null
    $ssrsDefinition = $ssrsProxy.GetItemDefinition($ssrsItem.Path)
 
    # Download the actual bytes
    [System.IO.MemoryStream] $memoryStream = New-Object System.IO.MemoryStream(@(,$ssrsDefinition))
    $ssrsFile.Load($memoryStream)
    $fullDataSourceFileName = $downloadFolderSub + "\" + $ssrsItem.Name +  $extension;
    $ssrsFile.Save($fullDataSourceFileName);
}

2
投票

这是基于 SQL2016/SSRS2016 但我认为它应该适用于 2012 年。

SELECT 'http://mySQLServerName/reports/api/v1.0/catalogitems(' + cast(itemid as varchar(256))+ ')/Content/$value' AS url
    FROM ReportServer.dbo.Catalog

这将为您提供一份 URL 列表,每个报告对应一个 URL。

如果上述方法在 SSRS 2012 中不起作用,请转到报告管理器并按照从那里下载文件的方式进行操作。检查下载按钮上的 URL,您可能会看到一个 URL,其中嵌入了项目 ID。只需调整上面的代码以匹配该 url 结构即可。

之后你要做什么取决于你。 就我个人而言,我会使用 Chrome 商店here中提供的名为“Tab Save”的 Chrome 扩展程序。您只需将上面创建的所有 URL 复制并粘贴到其中,然后点击下载按钮...


2
投票

如果您仅需要此用于备份目的或类似目的,这可能很有用:已发布的 RDL 文件位于何处?

该线程的相关查询是:

select convert(varchar(max), convert(varbinary(max), content))
from catalog
where content is not null

最初的答案是使用2005年,我在2016年使用过它,所以我想它应该适用于2008年和2012年。

当我必须使用它时,我也将路径添加到查询中,以便我知道哪个报告是哪个。

警告:在 SSMS v18 之前,结果到网格的大小限制为每个元组 64KB,结果到文本的大小限制为每个元组 8,192 个字符。如果您的报告定义大于这些限制,您将无法获得完整的定义。

在 SSMS v18 中,对于网格报告和文本结果,这些限制已增加到每个元组 2MB。


1
投票

我尝试了此脚本的几种排列,但不断收到“无法创建代理连接”错误。这是“应该”起作用的:

#------------------------------------------------------
#Prerequisites
#Install-Module -Name ReportingServicesTools
#------------------------------------------------------

#Lets get security on all folders in a single instance
#------------------------------------------------------
#Declare SSRS 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\SSRS\HQMNBI' -Recurse

这是我遇到的错误:

无法与 http://hqmnbi/ReportServer_SQL08/ReportService2010.asmx 建立代理连接:HTML 文档不包含 Web 服务发现信息。 在 C:\Program Files\WindowsPowerShell\Modules\ReportingServicesTools .0.6.6\Functions\Utilities\New-RsWebServiceProxy.ps1:136 char:9

  •     throw (New-Object System.Exception("Failed to establish proxy ...
    
  •     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • 类别信息:操作已停止:(:) [],异常
    • FullyQualifiedErrorId:无法与 http://hqmnbi/ReportServer_SQL08/ReportService2010.asmx 建立代理连接:
      HTML 文档不包含 Web 服务发现信息。

我尝试过使用 htttp:// 的 URI,也尝试过不包含端口号的 URI。等等。仍然无法让它真正发挥作用。我们还有另外两个 SSRS 实例,我可以毫无问题地运行它。


1
投票

来自这个问题:SQL Reporting Services - 将报告复制到另一个文件夹

我发现这个工具既可以下载也可以上传报告。另外它还列出了文件夹和子文件夹。

http://code.google.com/p/reportsync/


1
投票

关于这个问题: 无法建立与 http://hqmnbi/ReportServer_SQL08/ReportService2010.asmx 的代理连接: HTML 文档不包含 Web 服务发现信息。在 C:\Program Files\WindowsPowerShell\Modules\ReportingServicesTools .0.6.6\Functions\Utilities\New-RsWebServiceProxy.ps1:136 char:9

有同样的错误,所以我用这个代替: 而不是这一行: $sourceRsUri =“http://hqmnbi:80/ReportServer_SQL08/ReportService2010.asmx?wsdl”

用这个:

$sourceRsUri =“https://hqmnbi:80/ReportServer_SQL08/ReportService2010.asmx?wsdl”

然后一切都没有问题 - 代理和所有


0
投票

我尝试使用已接受的答案,但遇到了一些问题。因此,我编写了一个脚本来使用 REST SSRS 端点。该脚本适用于 Windows 上的 Powershell 7.x。我认为如果适当更改路径分隔符,它可以在其他平台上与 Powershell 一起使用。

#------------------------------------------------------
#Prerequisites
#Install-Module -Name ReportingServicesTools
#------------------------------------------------------

$sourceRsUri = 'https://ssrs.ourcompany.com/reports'
$localRoot = 'C:\Development\MySSRSProject\Server RDL Backup'

# create all the folders first.
$folders = Get-RsRestFolderContent / -Recurse -ReportPortalUri $sourceRsUri | Where-Object Type -eq 'Folder'
foreach($folder in $folders)
{
    # create each folder locally
    $localFolder = $localRoot + $folder.Path
    if (!(Test-Path $localFolder)) {
        New-Item -ItemType Directory -Path $localFolder
    }
}

# download the reports
$reports = Get-RsRestFolderContent / -Recurse -ReportPortalUri $sourceRsUri | Where-Object Type -eq 'Report'
# clear out modified date file:
Clear-Content ($localRoot + "\lastModified.txt")
foreach($report in $reports)
{
    # download each report to appropriate folder
    $localFolder = $localRoot + $report.Path

    # replace '/' with '\' in path
    $localFolder = $localFolder.Replace('/', '\')

    #remove report name from path
    $localFolder = $localFolder.Substring(0, $localFolder.LastIndexOf("\"))

    Out-RsRestCatalogItem $report.Path -ReportPortalUri $sourceRsUri -Destination $localFolder -Overwrite

    # write report last modified date and by to a file:
    $outString = $report.Path + " last modified by " + $report.ModifiedBy + " on " + $report.ModifiedDate.ToString("yyyy-MM-dd HH:mm:ss")
    $outString | Out-File -FilePath ($localRoot + "\lastModified.txt") -Append

}
© www.soinside.com 2019 - 2024. All rights reserved.