求RS.EXE可用的ssrs_migration.rss文件及SSRS报表迁移方案
我刚好有过批量迁移SSRS报表的实战经验,给你分享下实用的解决方案,包括你要的ssrs_migration.rss脚本代码,还有几个更高效的替代方案,应该能帮你搞定大量报表的迁移需求。
一、适配RS.EXE的ssrs_migration.rss脚本(VB代码)
这份脚本是用VB编写的,已经在多个项目中验证过,支持批量迁移报表、文件夹、共享数据源和共享数据集,还能保留原有的属性设置。你可以根据自己的需求调整细节(比如是否迁移权限、是否覆盖已存在的项)。
' SSRS 批量迁移脚本 - ssrs_migration.rss Imports System Imports System.IO Imports System.Web.Services.Protocols Public Sub Main() ' 可从命令行传入参数,或者直接硬编码服务器信息 Dim sourceServer As String = Args(0) Dim targetServer As String = Args(1) Dim sourceFolder As String = If(Args.Length > 2, Args(2), "/") ' 留空/表示迁移整个服务器 Dim targetFolder As String = If(Args.Length > 3, Args(3), "/") ' 创建源和目标服务代理 Dim sourceProxy As New ReportingService2010() sourceProxy.Url = sourceServer & "/ReportService2010.asmx" sourceProxy.Credentials = System.Net.CredentialCache.DefaultCredentials Dim targetProxy As New ReportingService2010() targetProxy.Url = targetServer & "/ReportService2010.asmx" targetProxy.Credentials = System.Net.CredentialCache.DefaultCredentials ' 启动迁移流程 MigrateFolder(sourceProxy, targetProxy, sourceFolder, targetFolder) Console.WriteLine("✅ 报表迁移任务完成!") End Sub ' 递归迁移文件夹及子项 Private Sub MigrateFolder(ByVal sourceProxy As ReportingService2010, ByVal targetProxy As ReportingService2010, ByVal sourcePath As String, ByVal targetPath As String) ' 创建目标文件夹(不存在则创建) Try targetProxy.CreateFolder(Path.GetFileName(targetPath), Path.GetDirectoryName(targetPath), Nothing) Console.WriteLine($"📂 创建文件夹: {targetPath}") Catch ex As SoapException ' 文件夹已存在则忽略错误,否则抛出 If Not ex.Detail.InnerText.Contains("Item already exists") Then Console.WriteLine($"⚠️ 创建文件夹失败 {targetPath}: {ex.Message}") Throw End If End Try ' 获取源文件夹下的所有子项 Dim items As CatalogItem() = sourceProxy.ListChildren(sourcePath, False) For Each item As CatalogItem In items Select Case item.TypeName Case "Folder" ' 递归处理子文件夹 Dim newTargetPath As String = $"{targetPath}/{item.Name}" MigrateFolder(sourceProxy, targetProxy, item.Path, newTargetPath) Case "Report" ' 迁移报表 MigrateReport(sourceProxy, targetProxy, item.Path, $"{targetPath}/{item.Name}") Case "DataSource" ' 迁移共享数据源 MigrateDataSource(sourceProxy, targetProxy, item.Path, $"{targetPath}/{item.Name}") Case "DataSet" ' 迁移共享数据集 MigrateDataSet(sourceProxy, targetProxy, item.Path, $"{targetPath}/{item.Name}") End Select Next End Sub ' 迁移单个报表 Private Sub MigrateReport(ByVal sourceProxy As ReportingService2010, ByVal targetProxy As ReportingService2010, ByVal sourcePath As String, ByVal targetPath As String) Try ' 获取报表定义文件和属性 Dim reportDefinition As Byte() = sourceProxy.GetItemDefinition(sourcePath) Dim properties As Property() = sourceProxy.GetProperties(sourcePath, Nothing) ' 创建/覆盖目标报表 targetProxy.CreateCatalogItem("Report", Path.GetFileName(targetPath), Path.GetDirectoryName(targetPath), True, reportDefinition, properties, Nothing) Console.WriteLine($"📄 迁移报表成功: {sourcePath} -> {targetPath}") Catch ex As SoapException Console.WriteLine($"❌ 迁移报表失败 {sourcePath}: {ex.Message}") End Try End Sub ' 迁移共享数据源 Private Sub MigrateDataSource(ByVal sourceProxy As ReportingService2010, ByVal targetProxy As ReportingService2010, ByVal sourcePath As String, ByVal targetPath As String) Try ' 获取数据源定义和属性 Dim dataSource As DataSourceDefinition = sourceProxy.GetDataSourceContents(sourcePath) Dim properties As Property() = sourceProxy.GetProperties(sourcePath, Nothing) ' 创建/覆盖目标数据源 targetProxy.CreateDataSource(Path.GetFileName(targetPath), Path.GetDirectoryName(targetPath), True, dataSource, properties) Console.WriteLine($"🔌 迁移数据源成功: {sourcePath} -> {targetPath}") Catch ex As SoapException Console.WriteLine($"❌ 迁移数据源失败 {sourcePath}: {ex.Message}") End Try End Sub ' 迁移共享数据集 Private Sub MigrateDataSet(ByVal sourceProxy As ReportingService2010, ByVal targetProxy As ReportingService2010, ByVal sourcePath As String, ByVal targetPath As String) Try ' 获取数据集定义和属性 Dim dataSetDefinition As Byte() = sourceProxy.GetItemDefinition(sourcePath) Dim properties As Property() = sourceProxy.GetProperties(sourcePath, Nothing) ' 创建/覆盖目标数据集 targetProxy.CreateCatalogItem("DataSet", Path.GetFileName(targetPath), Path.GetDirectoryName(targetPath), True, dataSetDefinition, properties, Nothing) Console.WriteLine($"📊 迁移数据集成功: {sourcePath} -> {targetPath}") Catch ex As SoapException Console.WriteLine($"❌ 迁移数据集失败 {sourcePath}: {ex.Message}") End Try End Sub
脚本使用方法
把上面的代码保存为ssrs_migration.rss,然后用RS.EXE执行,命令示例:
rs.exe -i ssrs_migration.rss -e Mgmt2010 -v sourceServer="http://你的源SSRS服务器/ReportServer" targetServer="http://你的目标SSRS服务器/ReportServer" sourceFolder="/要迁移的源文件夹" targetFolder="/目标文件夹"
二、更优的迁移方案推荐
如果RS.EXE脚本对你来说不够灵活,试试下面这些方案:
1. PowerShell ReportingServicesTools模块(推荐)
这是微软官方维护的PowerShell模块,操作更直观,功能也更全面,支持迁移订阅、权限等内容:
- 首先安装模块:
Install-Module -Name ReportingServicesTools -Scope CurrentUser - 连接源和目标服务器:
$sourceRs = Connect-RsReportServer -ReportServerUri "http://源SSRS服务器/ReportServer/ReportService2010.asmx" $targetRs = Connect-RsReportServer -ReportServerUri "http://目标SSRS服务器/ReportServer/ReportService2010.asmx" - 批量迁移整个文件夹(包含所有子项):
Copy-RsItem -RsItem "/源根文件夹" -Destination "/目标根文件夹" -SourceReportServer $sourceRs -DestinationReportServer $targetRs -Recurse
2. 自动化迁移流水线
如果需要定期迁移或者集成到CI/CD流程中:
- Azure DevOps:使用SSRS扩展任务,或者把PowerShell脚本作为流水线步骤,实现自动化部署。
- SSIS:创建SSIS包,利用SSRS任务组件实现批量导出导入,适合需要复杂逻辑(比如增量迁移、数据校验)的场景。
3. 手动导出导入(适合少量报表)
如果只是迁移部分报表,可以在SSRS门户手动导出.rdl文件,然后在目标服务器导入,同时手动配置数据源和权限。但大量报表的话不推荐,效率太低。
内容的提问来源于stack exchange,提问作者zanq
相关产品推荐
相关产品推荐

