Skip to content

Instantly share code, notes, and snippets.

@kulmam92
Forked from jstangroome/Deploy-SSRSProject.ps1
Last active May 16, 2017 22:48
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kulmam92/6433572 to your computer and use it in GitHub Desktop.
Save kulmam92/6433572 to your computer and use it in GitHub Desktop.
Deploy SSRS 2012 project to a Reporting server using ReportService2010 management endpoint(ReportService2010.asmx?WSDL)
#requires -version 2.0
<#
.SYNOPSIS
Deploy SSRS project to a Reporting server.
.DESCRIPTION
The Deploy-SSRSProject script installs an SSRS project(DataSource, DataSet, Report) file to a Reporting Server using ReportService20XX management endpoint.
http://technet.microsoft.com/en-us/library/ee640743(v=sql.105).aspx
1. Get datasource, report from the .rptproj file
2. Get report list from the $ReportListFile file
3. Deploy that to a reporting service
Works for 2012 and higher
.EXAMPLE
Deploy-SSRSProject.ps1 -Path "D:\App_temp\SSRS\DeployDemo\DeployDemo\DeployDemo.rptproj" -Configuration "Debug" -ReportListFile "D:\App_temp\SSRS\DeployDemo\ReportList.txt"
.EXAMPLE : this will pop up authentication window
$cred = Get-Credential
Deploy-SSRSProject.ps1 -Path "D:\App_temp\SSRS\DeployDemo\DeployDemo\DeployDemo.rptproj" -Configuration "Debug" -ReportListFile "D:\App_temp\SSRS\DeployDemo\ReportList.txt" -Credentials $cred
.EXAMPLE
Deploy-SSRSProject.ps1 -Path "D:\App_temp\SSRS\DeployDemo\DeployDemo\DeployDemo.rptproj" -Configuration "Debug" -ReportListFile "D:\App_temp\SSRS\DeployDemo\ReportList.txt" (get-credential) -Verbose
This command install the reports in the ReportList.txt from the DeployDemo project to Reporting Service defined in the Debug Configuration.
.NOTES
Version History
v1.0 - Jason Stangroome - 7/7/2012 https://gist.github.com/codeassassin/3043878
v1.1 - SpeakSQL.wordpress.com - 6/6/2013 - Modified to work on ReportService2010 management endpoint.
v1.2 - SpeakSQL.wordpress.com - 8/5/2013 - Added report list parameter.
#>
[CmdletBinding()]
param (
[parameter(Mandatory=$true)]
[ValidatePattern('\.rptproj$')]
[ValidateScript({ Test-Path -PathType Leaf -Path $_ })]
[string]
$Path,
[parameter(
ParameterSetName='Configuration',
Mandatory=$true)]
[string]
$Configuration,
[parameter(
ParameterSetName='Target',
Mandatory=$true)]
[ValidatePattern('^https?://')]
[string]
$ServerUrl,
[parameter(
ParameterSetName='Target',
Mandatory=$true)]
[string]
$Folder,
[parameter(
ParameterSetName='Target',
Mandatory=$true)]
[string]
$DataSourceFolder,
[parameter(ParameterSetName='Target')]
[switch]
$OverwriteDataSources,
[string]
$ReportListFile="ReportList.txt",
[System.Management.Automation.PSCredential]
$Credential
)
function New-XmlNamespaceManager ($XmlDocument, $DefaultNamespacePrefix) {
$NsMgr = New-Object -TypeName System.Xml.XmlNamespaceManager -ArgumentList $XmlDocument.NameTable
$DefaultNamespace = $XmlDocument.DocumentElement.GetAttribute('xmlns')
if ($DefaultNamespace -and $DefaultNamespacePrefix) {
$NsMgr.AddNamespace($DefaultNamespacePrefix, $DefaultNamespace)
}
return ,$NsMgr # unary comma wraps $NsMgr so it isn't unrolled
}
function Normalize-SSRSFolder (
[string]$Folder
) {
if (-not $Folder.StartsWith('/')) {
$Folder = '/' + $Folder
}
return $Folder
}
function New-SSRSFolder (
$Proxy,
[string]
$Name
) {
Write-Verbose "New-SSRSFolder -Name $Name"
$Name = Normalize-SSRSFolder -Folder $Name
if ($Proxy.GetItemType($Name) -ne 'Folder') {
$Parts = $Name -split '/'
$Leaf = $Parts[-1]
$Parent = $Parts[0..($Parts.Length-2)] -join '/'
if ($Parent) {
New-SSRSFolder -Proxy $Proxy -Name $Parent
} else {
$Parent = '/'
}
$Proxy.CreateFolder($Leaf, $Parent, $null)
}
}
function New-SSRSDataSource (
$Proxy,
[string]$RdsPath,
[string]$Folder,
[switch]$Overwrite
) {
Write-Verbose "New-SSRSDataSource -RdsPath $RdsPath -Folder $Folder"
$Folder = Normalize-SSRSFolder -Folder $Folder
[xml]$Rds = Get-Content -Path $RdsPath
$ConnProps = $Rds.RptDataSource.ConnectionProperties
$Definition = New-Object -TypeName SSRS.ReportingService2010.DataSourceDefinition
$Definition.ConnectString = $ConnProps.ConnectString
$Definition.Extension = $ConnProps.Extension
try {
if ([Convert]::ToBoolean($ConnProps.IntegratedSecurity)) {
$Definition.CredentialRetrieval = 'Integrated'
}
}
catch
{
}
$DataSource = New-Object -TypeName PSObject -Property @{
Name = $Rds.RptDataSource.Name
Path = $Folder + '/' + $Rds.RptDataSource.Name
}
if ($Overwrite -or $Proxy.GetItemType($DataSource.Path) -eq 'Unknown') {
$Results=$Proxy.CreateDataSource($DataSource.Name, $Folder, $Overwrite, $Definition, $null)
}
return $DataSource
}
$script:ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
$PSScriptRoot = $MyInvocation.MyCommand.Path | Split-Path
$Path = $Path | Convert-Path
$ProjectRoot = $Path | Split-Path
#Load project(.rptproj) file
[xml]$Project = Get-Content -Path $Path
#Get deployment environment information from the "Configuration" element
if ($PSCmdlet.ParameterSetName -eq 'Configuration') {
$Config = & $PSScriptRoot\Get-SSRSProjectConfiguration.ps1 -Path $Path -Configuration $Configuration
$ServerUrl = $Config.ServerUrl
$Folder = $Config.Folder
$DataSourceFolder = $Config.DataSourceFolder
$OverwriteDataSources = $Config.OverwriteDataSources
}
#Get folder information for DataSource and Report
$Folder = Normalize-SSRSFolder -Folder $Folder
$DataSourceFolder = Normalize-SSRSFolder -Folder $DataSourceFolder
#Connect to the ReportService20XX management endpoint
$Proxy = & $PSScriptRoot\New-SSRSWebServiceProxy.ps1 -Uri $ServerUrl -Version "ReportService2010" -Credential $Credential
#Create folder information for DataSource and Report
New-SSRSFolder -Proxy $Proxy -Name $Folder
New-SSRSFolder -Proxy $Proxy -Name $DataSourceFolder
#Create DataSource
$DataSourcePaths = @{}
$Project.SelectNodes('Project/DataSources/ProjectItem') |
ForEach-Object {
$RdsPath = $ProjectRoot | Join-Path -ChildPath $_.FullPath
$DataSource = New-SSRSDataSource -Proxy $Proxy -RdsPath $RdsPath -Folder $DataSourceFolder
$DataSourcePaths.Add($DataSource.Name, $DataSource.Path)
}
#Create Report
$Project.SelectNodes('Project/Reports/ProjectItem') |
ForEach-Object {
$RdlPath = $ProjectRoot | Join-Path -ChildPath $_.FullPath
[xml]$Definition = Get-Content -Path $RdlPath
$NsMgr = New-XmlNamespaceManager $Definition d
$RawDefinition = Get-Content -Encoding Byte -Path $RdlPath
$UploadReport = $false
$Name = $_.Name -replace '\.rdl$',''
$ReportList = [IO.File]::ReadAllText("$ReportListFile")
# Check if the report is defined to be uploaded
if ($ReportList -eq "*" -or $ReportList -eq $NULL -or $ReportList -eq "") {
$UploadReport = $true
}
else {
$ReportLists = $ReportList.split(",")
foreach($l in $ReportLists){
if ($Name -like $l) {
$UploadReport = $true
break
}
}
}
if ($UploadReport) {
Write-Verbose "Creating report $Name"
#2005
#$Results = $Proxy.CreateReport($Name, $Folder, $true, $RawDefinition, $null)
#2010 The CreateReport API was replaced with the more generic CreateCatalogItem API in 2010
$Results = $null
$Proxy.CreateCatalogItem("Report",$Name,$Folder,$true,$RawDefinition,$null,[Ref]$Results) | out-null
if ($Results -and ($Results | Where-Object { $_.Severity -eq 'Error' })) {
throw 'Error uploading report'
}
$Xpath = 'd:Report/d:DataSources/d:DataSource/d:DataSourceReference/..'
$DataSources = $Definition.SelectNodes($Xpath, $NsMgr) |
ForEach-Object {
$DataSourcePath = $DataSourcePaths[$_.DataSourceReference]
if (-not $DataSourcePath) {
throw "Invalid data source reference '$($_.DataSourceReference)' in $RdlPath"
}
$Reference = New-Object -TypeName SSRS.ReportingService2010.DataSourceReference
$Reference.Reference = $DataSourcePath
$DataSource = New-Object -TypeName SSRS.ReportingService2010.DataSource
$DataSource.Item = $Reference
$DataSource.Name = $_.Name
$DataSource
}
if ($DataSources) {
$Proxy.SetItemDataSources($Folder + '/' + $Name, $DataSources)
}
}
}
#requires -version 2.0
[CmdletBinding()]
param (
[parameter(Mandatory=$true)]
[ValidatePattern('\.rptproj$')]
[ValidateScript({ Test-Path -PathType Leaf -Path $_ })]
[string]
$Path,
[parameter(Mandatory=$true)]
[string]
$Configuration
)
function Normalize-SSRSFolder (
[string]$Folder
) {
if (-not $Folder.StartsWith('/')) {
$Folder = '/' + $Folder
}
return $Folder
}
$script:ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
Write-Verbose "$($MyInvocation.MyCommand.Name) -Path $Path -Configuration $Configuration"
[xml]$Project = Get-Content -Path $Path
$Config = $Project.SelectNodes('Project/Configurations/Configuration') |
Where-Object { $_.Name -eq $Configuration } |
Select-Object -First 1
if (-not $Config) {
throw "Could not find configuration $Configuration."
}
$OverwriteDataSources = $false
if ($Config.Options.SelectSingleNode('OverwriteDataSources')) {
$OverwriteDataSources = [Convert]::ToBoolean($Config.Options.OverwriteDataSources)
}
return New-Object -TypeName PSObject -Property @{
ServerUrl = $Config.Options.TargetServerUrl
Folder = Normalize-SSRSFolder -Folder $Config.Options.TargetFolder
DataSourceFolder = Normalize-SSRSFolder -Folder $Config.Options.TargetDataSourceFolder
OverwriteDataSources = $OverwriteDataSources
}
#requires -version 2.0
[CmdletBinding()]
param (
[parameter(Mandatory=$true)]
[ValidatePattern('^https?://')]
[string]
$Uri,
[parameter(
ParameterSetName='ReportService2010',
Mandatory=$true)]
[string]
$Version,
[System.Management.Automation.PSCredential]
$Credential
)
$script:ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
if (-not $Uri.EndsWith('.asmx')) {
if (-not $Uri.EndsWith('/')) {
$Uri += '/'
}
if($Version -eq 'ReportService2010'){
$Uri += 'ReportService2010.asmx?WSDL'
} else {
$Uri += 'ReportService2005.asmx'
}
}
$Assembly = [AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object {
if($Version -eq 'ReportService2010'){
$_.GetType('SSRS.ReportingService2010.ReportingService2010')
} else {
$_.GetType('SSRS.ReportingService2010.ReportingService2005')
}
}
if (($Assembly | Measure-Object).Count -gt 1) {
throw 'AppDomain contains multiple definitions of the same type. Restart PowerShell host.'
}
if (-not $Assembly) {
if ($Credential) {
$CredParams = @{ Credential = $Credential }
} else {
$CredParams = @{ UseDefaultCredential = $true }
}
if($Version -eq 'ReportService2010'){
$Proxy = New-WebServiceProxy -Uri $Uri -Namespace SSRS.ReportingService2010 @CredParams
} else {
$Proxy = New-WebServiceProxy -Uri $Uri -Namespace SSRS.ReportingService2005 @CredParams
}
} else {
if($Version -eq 'ReportService2010'){
$Proxy = New-Object -TypeName SSRS.ReportingService2010.ReportingService2010
} else {
$Proxy = New-Object -TypeName SSRS.ReportingService2005.ReportingService2005
}
if ($Credential) {
$Proxy.Credentials = $Credential.GetNetworkCredential()
} else {
$Proxy.UseDefaultCredentials = $true
}
}
$Proxy.Url = $Uri
return $Proxy
@dakotagurl
Copy link

I don't get the reasoning for the ParameterSetName='Target' I just get the error Parameter set cannot be resolved using the specified named parameters. + CategoryInfo : InvalidArgument: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : AmbiguousParameterSet
I can only go on until I comment them out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment