· Uwe Janke
Commands / Invoke-sqmSsrsMigration

Invoke-sqmSsrsMigration

SSRS MigrationsqmSQLTool v1.9.162+ · Migrate⚠ Content Manager on the affected folders  ✓ source stays untouched
Copying the .rdl files is not a migration. A report on the server is bound to its shared data sources and shared datasets by the catalog, not by the text in the RDL: Visual Studio deploys with TargetDataSourceFolder, and anyone can re-point a report in the web portal afterwards. Re-uploading only the RDL lands reports on the new server that point nowhere, or at a path that only existed on the old server. Stored data source passwords cannot be read through any API, so they are lost silently as well.

This command moves one or more report folders (a "report project") between two report servers, or to a different folder on the same server, and reports every item and every step. It works through the SSRS REST API v2.0 (SSRS 2017 and later, Power BI Report Server), so it runs the same under Windows PowerShell 5.1 and PowerShell 7. Nothing on the source is changed.

Bindings come from the source catalog, not from the RDL text. After uploading, the data sources of every report and shared dataset are set again from what the source server actually uses, with paths mapped to the destination, connection strings rewritten by -ConnectionStringMap and stored passwords supplied by -DataSourceCredential. Afterwards the bindings are read back from the destination and compared.

Dependencies outside the project are found and taken along. Shared data sources and datasets under /Data Sources or /Datasets that the migrated reports reference are copied to the same path on the destination; references that already point nowhere on the source are reported.

Parameters

ParameterTypeRequiredDefaultNotes
-SourceReportServerstringRequired—Source server. Accepts SRV, https://srv:8443, http://srv/ReportServer, http://srv/Reports, http://srv/ReportServer_INST or the full .../api/v2.0 URL for custom virtual directories.
-SourceCredentialPSCredentialOptionalcurrent userWindows credential for the source (NTLM/Kerberos).
-DestinationReportServerstringRequired—Destination server, same forms. May be the source server when -DestinationFolder differs.
-DestinationCredentialPSCredentialOptionalcurrent userWindows credential for the destination.
-SourceFolderstring[]Optional/Folder(s) to migrate, recursively.
-DestinationFolderstringOptionalsame pathPath that replaces -SourceFolder, e.g. /Finance → /Archive/Finance. Only with a single source folder. Absolute references inside RDL/RSD content follow the move.
-ItemTypestring[]OptionalallDataSource, DataSet, Report, LinkedReport, Resource, PowerBIReport, ExcelWorkbook. Folders are always created as needed.
-ConnectionStringMapstring[]Optional—Replacements as 'OLD=>NEW', case-insensitive, for shared and embedded data sources.
-DataSourceCredentialPSCredential[]Optional—Passwords for data sources with stored credentials, matched by the stored user name (DOM\user also matches user). Missing passwords are listed in the plan.
-OverwriteswitchSwitch$falseOverwrite existing reports, datasets, resources and linked reports. The item keeps its ID, so destination subscriptions and history stay attached. Each overwritten item is backed up first.
-OverwriteDataSourcesswitchSwitch$falseAlso overwrite existing shared data sources. Separate on purpose: an existing data source on the destination usually carries the right connection and password for that environment.
-IncludeSecurityswitchSwitch$falseCopy role assignments of every folder and item that breaks inheritance. Users, groups and role names must exist on the destination.
-SkipDependenciesswitchSwitch$falseDo not take along referenced data sources/datasets outside the source folders.
-SkipCertificateCheckswitchSwitch$falseAccept untrusted HTTPS certificates.
-AssessOnlyswitchSwitch$falseInventory and plan only. Changes nothing on the destination.
-OutputPathstringOptional<config>\SsrsMigrationHTML report, source export (Source\) and backup of overwritten items (DestinationBackup\).
-NoOpen / -NoReportswitchSwitch$falseDo not open the report / do not write one (the export is still written).
-EnableExceptionswitchSwitch$falseThrow immediately instead of returning a result object with Status 'Failed'.
Supports -WhatIf and -Confirm (ConfirmImpact High). A -WhatIf run builds the complete plan, returns it in .Items and writes nothing.

Execution Flow

START Connect to both servers GET /System: version, authentication, REST API present Inventory source folders Data source definitions, report and dataset bindings, shared dataset references, linked report targets, policies, subscriptions Resolve dependencies outside the folders /Data Sources, /Datasets ... taken along at their original path Plan against the destination Create / Overwrite / Skip / type conflict, missing stored passwords -AssessOnly or -WhatIf? YES Return plan and report Nothing is written NO Export source, back up items that will be overwritten Source\... and DestinationBackup\... below the report folder Write in dependency order Folders → data sources → datasets → resources → reports → linked reports → PBI Overwrite = PATCH on the existing ID Re-apply bindings from the source catalog Mapped paths, ConnectionStringMap, stored passwords Item security (-IncludeSecurity) Only items that break inheritance Verify: read bindings back from the destination Deviations turn the item into Warning Result + HTML report

Examples

The planning run: contents, dependencies, what exists already, which passwords are missing
Invoke-sqmSsrsMigration -SourceReportServer SSRSOLD -DestinationReportServer SSRSNEW -SourceFolder '/Finance' -AssessOnly
The migration, with data sources re-pointed to the new database server
$cred = Get-Credential rpt_reader
Invoke-sqmSsrsMigration -SourceReportServer SSRSOLD -DestinationReportServer SSRSNEW `
    -SourceFolder '/Finance' -ConnectionStringMap 'SQLOLD01=>SQLNEW01' `
    -DataSourceCredential $cred -IncludeSecurity -Confirm:$false
Copy a project to a test folder on the same server; references follow the copy
Invoke-sqmSsrsMigration -SourceReportServer SSRS01 -DestinationReportServer SSRS01 `
    -SourceFolder '/Finance' -DestinationFolder '/Test/Finance' -Overwrite
Delta run after the first migration: replace changed reports, keep IDs and subscriptions
$r = Invoke-sqmSsrsMigration -SourceReportServer SSRSOLD -DestinationReportServer SSRSNEW `
    -SourceFolder '/Finance' -Overwrite -DataSourceCredential $cred -Confirm:$false
$r.Items | Format-Table Type, DestinationPath, Action, Status, Detail -AutoSize
Which subscriptions have to be recreated on the new server?
(Invoke-sqmSsrsMigration -SourceReportServer SSRSOLD -DestinationReportServer SSRSNEW -SourceFolder '/Finance' -AssessOnly).Subscriptions |
    Format-Table Report, Description, Owner, DeliveryExtension, IsDataDriven

Notes

What this does not do. Subscriptions are listed, not copied: they carry the owner, schedule and delivery settings of the old server and have to be recreated deliberately. Also not migrated: cache, history and snapshot settings, shared schedules, report parameters changed on the server, KPIs and mobile reports.

API quirks handled, measured against SSRS 2022. A shared data source created without IsConnectionStringOverridden = true is accepted (HTTP 201) but stored with an empty connection string. CredentialRetrieval is only accepted in lower case (store; Store returns HTTP 400). Linked reports can only be created through /LinkedReports, where Path is the parent folder, while every other item type expects the full path.

PowerShell 7 and plain http. PowerShell 7 refuses Windows authentication over http:// unless -AllowUnencryptedAuthentication is set, even though NTLM/Kerberos never sends a clear-text password. Many internal report servers run without TLS, so the command sets it under PowerShell 7 for http URLs; Windows PowerShell 5.1 does not need it.