SSRS PowerShell deserialize report to XML

Useful script/function to get report definition to XML. You can modify the xml and serialize it back to Report Server – so easy. Go to Connect to Reporting Services with PowerShell, to get script that connect to SSRS Web Service.

Parameters:

  • $proxy – proxy Web Service
  • $path – report path
function DeserializeReportDefinitionToXml($proxy,$path)
 {

[System.Xml.XmlDocument] $rdlFile = New-Object System.Xml.XmlDocument;  
[byte[]] $reportDefinition = $null          ;     
[System.IO.MemoryStream] $memStream              | Out-Null;
$reportDefinition                             | Out-Null;
 try{
    $reportDefinition = $proxy.GetReportDefinition($path);
}

catch{   Write-Host "Get report definition problem " $Error[0]
}
 
try{ 
$memStream = New-Object System.IO.MemoryStream(@(,$reportDefinition));
}
catch{
    Write-Host "Problem saving to memory " $Error[0]
}
 try{
$rdlFile.Load($memStream) ;
}
catch{
    Write-Host "Problem load from memory" $Error[0]
}
return $rdlFile
 }

Let’s try. Write-down hierarchy of groups of your Tablix. Use bellow mentioned function, set proxy and Report path (Report should contain Tablix). Be careful of xml namespace used in function. It depends on version of your Report Server.

function TablixRowHierarchy($proxy,$path){
[System.Xml.XmlDocument] $xml | Out-Null;
$xml=DeserializeReportDefinitionToXml $proxy $path ;
[System.Xml.XmlNamespaceManager] $_nsmgr | Out-Null;
 
try{
  $_nsmgr = $xml.nameTable -as [System.Xml.XmlNamespaceManager];
  $_nsmgr.AddNamespace("a", "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition");
}
catch{
 Write-Host "problem create namespace" $Error[0]
}
[int] $level1 = 0;
 
foreach ($node in $xml.SelectSingleNode("/a:Report/a:Body/a:ReportItems/a:Tablix/a:TablixRowHierarchy",$_nsmgr).SelectNodes9"//a:TablixMembers",$_nsmgr))
{
 foreach ($val in $node.SelectNodes("a:TablixMember/a:TablixHeader/a:CellContents/a:Textbox/a:Paragraphs/a:Paragraph/a:TextRuns/a:TextRun/a:Value",$_nsmgr))
{
   Write-Host "Node value " + $val.InnerText 
 }
Write-Host "Node name " + $node.Name
}
}

Connect to Reporting Services with PowerShell

In this post I will show you how to make connection to Reporting Web Service Endpoint trough PowerShell. Report Web Service contains following endpoints you can work with:

  • management endpoints
  • execution endpoints
  • SharePoint Endpoints

You can find more info on Microsoft Website https://bit.ly/2LmkNhg. In my post series I will use management endpoint ReportService2005.asmx. There is ReportingService2006.asmx which is designed for developers working in SharePoint mode and ReportingService2010.asmx designed for either SharePoint or native mode.

Goal

List Reporting Services respository through PowerShell commands.

Prerequisites

There are no extra prerequisites since PowerShell is part of .NET framework installed on most of Windows platforms by default. In case you would like update your PowerShell framework go to MSDN https://bit.ly/2xX3F92

For listing Reporting Services repository, we need two rows of commands put to your PowerShell console.

$proxy = New-WebServiceProxy "http://<yourservername>/Reportserver/ReportService2005.asmx" -Namespace SSRS.ReportingService2005 -UseDefaultCredential
$proxy.ListChildren("/blog",$true)
  • The first command uses new-webserviceProxy cmdlet returning Web service proxy object. It allows us to use all proxy methods, SSRS methods in our scenario.
  • In the second command we use to call Web service methods, List Children in our case

After putting these two commands to PowerShell console you will see list of Reporting Services repository items as output in PowerShell console.

You can write easily PowerShell script, to make the solution reusable and configurable like the example bellow.  PowerShell is powerful and fast tool for writing scripts that help you automatize your tasks and you do not need to be an experienced developer. Enjoy

Let’s put basic setup to configuration xml file.

<Configuration>
<SSRSSoap>
<Address>http://Server/ReportServer//reportservice2005.asmx
</Address>
<Credentials UserName="">DefaultCredential</Credentials>
</SSRSSoap>
</Configuration>

Script with function to get data from configuration file and function to connect to SSRS Web Service.

function SSRS-Get-Config-Data ($ConfigPath){
[xml] $xml|out-null 
try {
 $xml= [xml](Get-Content $ConfigPath)
    }
catch {
  Write-Host "Cannot read file" $Error[0]
}
[string] $address|out-null
[string] $credentials|out-null
[string] $credentialName |out-null
try {
    $address= (Select-Xml '//Configuration/SSRSSoap/Address' $xml).node.innertext
    $credentials= (Select-Xml '//Configuration/SSRSSoap/Credentials' $xml).node.innertext
    $credentialName=( Select-Xml '//Configuration/SSRSSoap/Credentials' $xml).node.UserName #.node.Attributes[0].Value
}
catch {
 Write-Host "Wrong file format" $Error[0]
}
$proxy|out-null
try {
if ($credentials -eq "DefaultCredential" )
{
 $proxy = New-WebServiceProxy -Uri $address -Namespace  SSRS.ReportingService2005 -UseDefaultCredential;
}
if ($credentials -eq "Credential" ) {
    $proxy = New-WebServiceProxy -Uri $address -Namespace  SSRS.ReportingService2005 -Credential $credentialName;
}
}
catch
{
Write-Host "Cannot connect to web service" $Error[0]
}
return ,$proxy;

}

function ConnectToWebService ($ConfigPath)
{
$proxy = SSRS-Get-Config-Data $ConfigPath
if ($proxy.GetType().Name -eq "ReportingService2005" ) # check for type
{
 return $proxy
}
}

Example

$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
. $scriptDir\function.ps1

$proxy = ConnectToWebService ".\config.xml"
$proxy.ListsChildren("/",$true)

example_powershell_connect

SSRS connect to web service

IIn most of scenarios I realized projects that report Data Sources connect to MS SQL database or to Analysis Services cubes. But reporting services provide you with possibility to connect to more data source types. In this post I would like to show you how to connect with report to Web Service and visualise data. We do not need to developed Web Service for this sample we will use the Reporting Services Web Service. Let’s suppose that we would like to visualise data in Reporting Services Repository.

It can be implemented in few ways. We can use for this task Reporting Services database for example but for our purposes we will use Reporting Services Web Service.

Goal

Create dataset returning data regarding Reporting Services Report Manager directories and reports.

Open Report Builder and create new file
or Microsoft
Visual Studio with Data Tools, create new project and add new Reporting Services report.

Go to Report Data pane, Data Sources section, right click and select Add Data Source.

Add Data Source
Picture 1 – Add Data Source

When Data Source Properties window appears, choose XML in Select connection type select box.

Connection Type
Picture 2 – Connection Type

In Data Source Properties dialog box put Connection string with URL address of your Reporting Services Web Service Endpoint. In my case I will use ReportService2005.asmx.

Data Source Properties
Picture 3 – Data Source Properties

Create New dataset, select your created Data source DataSource1.

Add Dataset
Picture 4 – Add Dataset

Put following code to Query text area.

<Query>
<Method Name="ListChildren"
Namespace="http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices">
<Parameters>
<Parameter Name="Item" Type="String">
     <DefaultValue>/</DefaultValue>
</Parameter>
<Parameter Name="Recursive" Type="Boolean">
<DefaultValue>1</DefaultValue>
</Parameter>
</Parameters>
</Method>
<ElementPath IgnoreNamespaces="true">*</ElementPath>
</Query>

If we look at the code above, we can see that we need to specify method name and its parameters. Everything you need you can find you put URL of We Service Endpoint to your browser. There you can find all methods the web service supports. The code mentioned above is syntax used for Report XML Data Sources. Find more info on the web https://bit.ly/2XvdCWB.

In our case we use Listchildren method which expects two parameters. Item – parent item, the method starts to list, and Recursive specifying you would like to list all its parents recursively. Dataset Properties pane should look like on picture bellow.

Add Dataset Properties
Picture 5 – Add Dataset Properties

Voila and we can see items in our dataset. You can link the dataset with the Tablix of your report. As you can see web service gives us information regarding Name and Path of a report or when and by whom was the report created or modified.

Dataset Fields
Picture 6 – Dataset Fields

In next post I will implement recursive Tablix report with the dataset created in this post. Stay tuned.