A script to deploy SSRS reports

In many projects required the installation script or package that performs the update server part of the application. The need in the first place, due to the lack of direct access to the production server, developers.
The installer in the form of script is best suited for installations without an explicit logon to the server (RDP). Also the script can be executed as a single loader, which will do the rest. In current projects we implemented something like PsGet[1], except for the internal build server.
The application is large and consists of several components, one of which is a reporting module, built on the base SSRS.

To manage the server reporting Microsoft gave developers a web service ReportingService2005.asmx[2].

Pre-installation


Initial installation and configuration of reporting server is not included in the responsibility of developers and is done by teams with certain responsibilities. Also we do not create Data Sources since they might contain sensitive information (such as passwords to connect).
As a result, the above settings, and access the script you need to do. It only remains to add and update the reports themselves.

connecting to the service


PowerShell 2.0 provides the ability to create proxies for the web service via the command New-WebServiceProxy[3].
It is sufficient to specify the path to a service description WSDL[4]. We are using Windows Authentication, so the connection will specify the key UseDefaultCredential. In the proxy service, you must also specify the authentication method.
the
function Connect-ReportingService([string]$ssrsHost)
{
$reportingServiceUrl = $ssrsHost + "ReportService2005.asmx?wsdl"
$reportingService= New-WebServiceProxy $reportingServiceUrl -UseDefaultCredential -namespace ReportingWebService
$reportingService.UseDefaultCredentials = $true
$reportingService
}

$SsrsHost contains the full path, which is configured to our service (usually, servername/ReportServer).

add a report


To create or refresh the report, there is a method CreateReport[5].
As parameters it takes the report name, the name of the parent folder (folders allow you to group reports and ask them various security policies), the flag necessary, rewrite the binary file content of the report and the additional properties (usually not used, you can pass $null).
The method returns a collection of error messages and warnings.
From them, we will ignore the messages about Data Sources.
The call will look like:
the
(Connect-ReportingService $ssrsHost).CreateReport($report, $ssrsFolder, $true, $reportBits, $null)

Thus the addition of the report can be wrapped in a function:
the
function Deploy-Report([string]$ssrsHost, [string]$reportDir, [string]$report, [string]$ssrsFolder)
{
<#
here a relative path is specified, in which
there is a report (specific to project)
#>
$relativeReportLocation = "..\RS\$($report).rdl"

# check existence of file
if (-not (Test-Path $reportFile))
{
$message = "Report file '{0}' was not found!" -f $reportFile
Write-Warning $message
return
}

# read report file
[byte[]]$reportBits = [System.IO.File]::ReadAllBytes($reportFile)

# in fact, add a report and get results
$warnings = (Connect-ReportingService $ssrsHost).CreateReport($report, $ssrsFolder, $true, $reportBits, $null)
# clean messages from the "extra"
$cleanedWarnings = $warnings | ? { -not $_.Message.Contains("data source") }

# print the result on the screen (depending on the number of errors)
if(!$cleanedWarnings)
{
$result = "Report '{0}' published successfully with no warnings" -f $report
Write-Host $result
Write-Host ""
}
else
{
$warningHeader = "Report '{0}' published with warnings: "-f $report
Write-Host $warningHeader 
$cleanedWarnings | % { 
Write-Warning $_.Message 
}

Write-Host ""
}
}


Conclusions


This implementation solves the problem of adding and updating a single report and can be used in such a code:
the
 ls "..\RS\*.rdl") | % { $_.Name.Replace(".rdl", "") } | % { Deploy-Report $ssrsHost $reportDir $report $ssrsFolder }

Calling web-services using PowerShell is trivial.

Extensions

In the current project we have implemented a bulk modulus of extension.

So, to update reports, you can also by the condition, for example, based on the last modification time of file[7]:
the
 # get the existing list of records (recursively)
$deployedReports = (Connect-ReportingService $config).ListChildren($ssrsFolder, 1)

[hashtable]$deployedReportsMap = @{}
$deployedReports | % { $deployedReportsMap[$_.Name + '.rdl'] = $_ }

ls "..\RS\*.rdl") `
| ? { 
( -not $deployedReportsMap.ContainsKey($_.Name)) -or 
$deployedReportsMap[$_.Name].ModifiedDate -lt $_.LastWriteTime
} `
| % { $_.Name.Replace(".rdl", "") } `
| % { Deploy-Report $ssrsHost $reportDir $report $ssrsFolder }

Sometimes it is necessary to update the Data Source for a report, what is the method of SetItemDataSources.
Often have to reset the cache for a report (method FlushCache).

In General, everything is simple and extensible.

    the
  1. psget.net
  2. the
  3. msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.aspx
  4. the
  5. technet.microsoft.com/en-us/library/dd315258.aspx
  6. the
  7. www.w3.org/TR/wsdl
  8. the
  9. msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.createreport.aspx
  10. the
  11. msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.createdatasource.aspx
  12. the
  13. the ListChildren method: msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.listchildren.aspx
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

The use of Lisp in production

FreeBSD + PostgreSQL: tuning the database server

As we did a free Noodle for iOS and how we plan to earn