Deploying SSRS Reports from Powershell

My current client has a BI group that writes SSRS reports.  In the "legacy" ALM tool they built, they used VSS, nAnt,Cruise Control and a product called "Visual Intercept" to "build" (actually just extract RDL files) and a nAnt script with a custom task to Deploy the SSRS report (RDL File) to Reporting Services.

We migrated to TFS and use a lot of Powrshell for the deploy scripts.  I searched for some solutions from Powershell to deploy RDL's that I felt was a good fit.  This solution: http://blogs.devhorizon.com/reza/?p=751 is for a Sharepoint Reporting Service Integration.  These are stand-alone SSRS reports - so I'm not even sure if I have the .DLL it relies on "ReportService2006.dl" so it was no go.

The other solution that looks quite promising, from Paul Stovell at Readify http://www.paulstovell.com/blog/reporting-services-automation is an excellent approach, but relies on a utility "rs.exe".  But that wasn't installed on the server they run the deploys from (actually the TFS Build server for the time being) and I didn't want any dependencies I didn't have complete control over.

Being a C# guy - I figured the easiest thing was just to write copy the code from the original nAnt custom Task that called the SSRS Web Service to Deploy the report.  I wrote a very simple Wrapper to the webservice as a Static Method to a Static Class.  I then just copy the generated DLL's to the Build/Deploy server - and call that wrapper from the Deploy script.  Simple enough.

I cleaned the original code a bit - adding an integer return that shows 0 for success, 4 for warnings and either 12 or 16 for a fatal error.  The C# Code is here.  I just added a .NET 2.0 style WebService Reference (as Derick Whitaker explains here: http://devlicio.us/blogs/derik_whittaker/archive/2008/07/21/referencing-2-0-web-services-asmx-in-visual-studio-2008.aspx  in case you don't know how) to http://localhost/reportserver/reportservice.asmx?wsdl (don't use ReportService2005.asmx - that's a different web service!)

C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Linq;
using System.Text;
using SSRSDeployer.ReportServer;
using System.Web.Services.Protocols;


namespace SSRSDeployer
{
    public static class SSRSDeployer
    {
        public static int Deploy(string webServiceURL, string rdlPath, string parentFolder, string reportName, out string warnings)
        {
            //create an instance of the WebService Proxy and set URL and credentials
            ReportingService rs = new ReportingService();
            rs.Url = webServiceURL;
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

            Byte[] definition = null;
            Warning[] warns = null;
            StringBuilder sb = new StringBuilder();
            int ret = 0;

            try
            {
               
                //read the file as a filestream into a byte array
                FileStream stream = File.OpenRead(rdlPath);
                definition = new Byte[stream.Length];
                stream.Read(definition, 0, (int)stream.Length);

                //    Call the web service to create the report
                rs.Timeout = 1000000;
                warns = rs.CreateReport(reportName, parentFolder, true, definition, null);

                if (warns != null)
                {
                    foreach (Warning warning in warns)
                    {
                        //ignore the warning about shared data source
                        if (!(warning.Message.StartsWith("The data set ‘") && warning.Message.Contains("’ refers to the shared data source ‘") && warning.Message.EndsWith("which is not published on the report server.")))
                        {
                            // otherwise return it to output
                            sb.Append(string.Format("Warning returned from WebService: {0}", warning.Message));
                            ret = 4;
                        }
                    }
                }
            }
            catch (IOException)
            {
                //report any IO error reading the RDL file
                sb.Append(string.Format("Error: IOExcption reading file: {0}", rdlPath));
                ret = 12;
            }

            catch (SoapException e)
            {
                //report any Errors from the WebService call
                sb.Append(e.Message);
                ret = 16;
            }

            warnings = sb.ToString();
            return ret;
        }
    }
}

 

To Call it from Powershell, simply load the assembly and call the Method: This Powershell script will deploy all RDL's found in the specified folder with a report name matching the file name.  Make sure you put all the generated DLL's from the compile to the folder referenced by the $lib= statement

[string] $webServiceURL = "http://SSRSServer/ReportServer/ReportService.asmx"
[string] $rdlPath = "C:\File13"
[string] $parentFolder = "/SSRS.Folder";

$file = Get-Item $rdlPath
$lib="C:\File13\SSRSDeployer\SSRSDeployer.dll"
$x=[Reflection.Assembly]::LoadFrom($lib)

$files = Get-ChildItem $rdlPath *.rdl
ForEach ($file in $files) {
 [string] $reportName = ([string] $file.Name.ToUpper()).Replace(".RDL","")
 [string] $warnings = ""
 "Deploying Report: $reportName"
 [Int32] $result = [SSRSDeployer.SSRSDeployer]::Deploy($webServiceURL, $file.FullName, $parentFolder, $reportName, [ref] $warnings)
 if ($result -eq 0) {"Deployed without Errors"}
 elseif ($result -eq 4) {"Warnings from Deploy: $warnings"}
 elseif ($result -eq 12) {"IO Error reading RDL File"}
 elseif ($result -eq 16) {"Error Deploying Report: $warnings"}
 }

 

Published 25 November 08 06:17 by DanielS
Filed under: ,

Comments

No Comments
Anonymous comments are disabled