【问题标题】:Download all SSRS reports下载所有 SSRS 报告
【发布时间】:2017-10-17 05:34:37
【问题描述】:

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

有什么方法或工具可以让我下载所有 .rdl 文件并复制它们吗?

【问题讨论】:

    标签: sql-server reporting-services ssrs-2008 ssrs-2012


    【解决方案1】:

    使用 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
    

    【讨论】:

    • 我希望我能投票 10 次。您刚刚为我节省了几个小时的工作时间。
    • 将 $sourceRsUri 放在单引号中对我不起作用,我必须使用双引号
    • 我得到了Unable to find type [Microsoft.ReportingServicesTools.ConnectionHost] - 这是在ReportingServicesTools 包中定义的。原来根本原因是从网络路径运行脚本。一旦我从我的 C 盘运行它,它就可以正常工作了。
    • 也适用于 SSRS 2017 和 2019!对于 SSRS 2017 - $sourceRsUri = 'ReportServerURL/ReportServer/ReportService2017.asmx?wsdl' 对于 SSRS 2019 - $sourceRsUri = 'ReportServerURL/ReportServer/ReportService2019.asmx?wsdl'
    • 我遇到了一个奇怪的问题。我指定$sourceRsUri 来查看/ReportService2012.asmx?wsdl,因为我正在运行SSRS 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/SSRS2016 但我认为它应该适用于 2012 年。

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

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

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

      在此之后如何处理取决于您。 我个人会使用 Chrome 商店here 中提供的名为“Tab Save”的 Chrome 扩展程序。您可以简单地将上面创建的所有 URL 复制并粘贴到其中,然后点击下载按钮...

      【讨论】:

        【解决方案5】:

        找到并使用它没有任何问题。无需安装,只需添加我的网址,然后粘贴到 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);
        }
        

        【讨论】:

          【解决方案6】:

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

          #------------------------------------------------------
          #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.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,但没有尝试包含端口号。等等。仍然无法让它真正起作用。我们还有另外两个 SSRS 实例,我可以毫无问题地运行它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多