Sunday, October 14, 2007

Report Services Automation With PowerShell

In late September Paul Stovell wrote about a set of VB.NET scripts he prepared to help deploy reports to SQL Server Reporting Services. If you've ever had the displeasure of deploying SSRS reports without Visual Studio then you'll understand how much it sucks.

Paul went to the effort to write individual scripts for creating folders and data sources on the server and uploading report definitions and configuring permissions. With Paul's work simple command scripts can then be used deploy reports.

However these command scripts still need to be written and they end up containing much of the same information as can be found in the .rptproj project file and the .rds data source files. I despise the idea of maintaining any sort of configuration information in more than one place so adding to the deploy command script whenever I add a report to the project in Visual Studio just makes me cringe.

Additionally, as Paul briefly mentions, MSBuild (and therefore Team Build) does not support Report Services projects so, once again, to deploy your reports as part of Continuous Integration you need to have separate tools.

Today I constructed a lengthy PowerShell script to take a Report Services .rptproj project file and output a command script that utilises Paul's VB.NET scripts to deploy the reports as per the project settings. Due to the size of the script rather than publishing it inline, you can download it here.

The script accepts three parameters. ProjectFile is the path to .rptproj file for the reports you want to deploy. If you omit this parameter the script uses the first report project file it finds in the current directory. The second parameter, ConfigurationName tells the script which project configuration to use for the target server URL and destination folders. If you omit this parameter the script uses the first configuration defined in the project. The last parameter SearchPaths is a list of paths for the script to search when locating both rs.exe and Paul's .rss files. The SearchPaths parameter is automatically combined with the environment PATH variable and may be omitted.

Here is an example usage:

PS C:\Users\Jason\Dev\MyReports> .\Deploy-SqlReports.ps1 `
    -ProjectName MyReports.rptproj `
    -ConfigurationName Release `
    -SearchPaths "C:\Tools\Report Services\" `
    | Out-File deploy.cmd -Encoding ASCII;

As always, my PowerShell skills are slowly improving and this script is not necessarily perfect in either robustness or efficient use of PowerShell. Hopefully it will be as useful to you as it has been to me and any changes you need should be easily made. Please leave a comment with your thoughts and suggestions.

Sunday, October 14, 2007 9:22:09 AM (Cen. Australia Standard Time, UTC+09:30)
Nice work Jason! Powershell rocks.

I can think of a few projects that could use this in a built script with the powershell msbuild task to deploy reports.
Monday, October 29, 2007 1:28:55 PM (Cen. Australia Standard Time, UTC+09:30)
Nice!
I am trying to make use of your script. However, I found one problem... I have to set data source manually or run "SetDataSource.rss" separately before my reports work.
Any advise on how to automate this part too?

Doon
Doon
Monday, October 29, 2007 8:36:33 PM (Cen. Australia Standard Time, UTC+09:30)
Hello Doon,

All of the reports I have deployed have used a shared data source defined in the project. In this case the powershell script generates the appropriate calls to configure the shared data source first then upload the reports and it works fine. However, I believe it is possible to have per-report data sources and I guess this is your situation.

Looking inside the report rdl file (which is just xml) there is a DataSources element which in my case refers to the shared data source but in your case you may find it contains a connection string and perhaps values similar to those found in a shared data source .rds file. The powershell script could definitely be modified to inspect each rdl file for internally defined datasources and create a SetDataSource line in the resulting command script.

If you need any more help, send me an email.

Regards,

--
Jason Stangroome
Comments are closed.