Skip to content

Instantly share code, notes, and snippets.

@ChrisMissal
Forked from jstangroome/Deploy-SSRSProject.ps1
Last active February 2, 2019 14:40
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ChrisMissal/5979564 to your computer and use it in GitHub Desktop.
#requires -version 2.0
[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,
[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.ReportingService2005.DataSourceDefinition
$Definition.ConnectString = $ConnProps.ConnectString
$Definition.Extension = $ConnProps.Extension
if ([Convert]::ToBoolean($ConnProps.IntegratedSecurity)) {
$Definition.CredentialRetrieval = 'Integrated'
}
$DataSource = New-Object -TypeName PSObject -Property @{
Name = $Rds.RptDataSource.Name
Path = $Folder + '/' + $Rds.RptDataSource.Name
}
if ($Overwrite -or $Proxy.GetItemType($DataSource.Path) -eq 'Unknown') {
$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
[xml]$Project = Get-Content -Path $Path
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
}
$Folder = Normalize-SSRSFolder -Folder $Folder
$DataSourceFolder = Normalize-SSRSFolder -Folder $DataSourceFolder
$Proxy = & $PSScriptRoot\New-SSRSWebServiceProxy.ps1 -Uri $ServerUrl -Credential $Credential
New-SSRSFolder -Proxy $Proxy -Name $Folder
New-SSRSFolder -Proxy $Proxy -Name $DataSourceFolder
$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)
}
$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
$Name = $_.Name -replace '\.rdl$',''
Write-Verbose "Creating report $Name"
$Results = $Proxy.CreateReport($Name, $Folder, $true, $RawDefinition, $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.ReportingService2005.DataSourceReference
$Reference.Reference = $DataSourcePath
$DataSource = New-Object -TypeName SSRS.ReportingService2005.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,
[System.Management.Automation.PSCredential]
$Credential
)
$script:ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
if (-not $Uri.EndsWith('.asmx')) {
if (-not $Uri.EndsWith('/')) {
$Uri += '/'
}
$Uri += 'ReportService2005.asmx'
}
$Assembly = [AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object {
$_.GetType('SSRS.ReportingService2005.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 }
}
$Proxy = New-WebServiceProxy -Uri $Uri -Namespace SSRS.ReportingService2005 @CredParams
} else {
$Proxy = New-Object -TypeName SSRS.ReportingService2005.ReportingService2005
if ($Credential) {
$Proxy.Credentials = $Credential.GetNetworkCredential()
} else {
$Proxy.UseDefaultCredentials = $true
}
}
$Proxy.Url = $Uri
return $Proxy
if (-not (Test-Path("cred2.txt"))) {
Write-Host "=========================================================" -foregroundcolor cyan
Write-Host "» To deploy the Debug configuration to localhost, type"
Write-Host "» your credentials. It will be stored as a SecureString"
Write-Host "» on disk, but not checked into source control."
Write-Host "» Username: " -foregroundcolor cyan; Read-Host | Out-File cred1.txt
Write-Host "» Password: " -foregroundcolor cyan; Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File cred2.txt
}
$pass = cat cred2.txt | ConvertTo-SecureString
$user = cat cred1.txt
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
Write-Host "Deployment started..." -foregroundcolor yellow
.\Deploy-SSRSProject.ps1 -Path 'pathtoproject\ProjectFile.rptproj' -Configuration 'Debug' -Credential $cred
Write-Host "Deployment finished!" -foregroundcolor green
$pass = ConvertTo-SecureString -AsPlainText -Force -String "password"
$user = "username"
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
Write-Host "Deployment started..." -foregroundcolor yellow
.\Deploy-SSRSProject.ps1 -Verbose -Path 'pathtoproject\ProjectFile.rptproj' -Configuration 'Release' -Credential $cred
Write-Host "Deployment finished!" -foregroundcolor green
@jdgonzalez
Copy link

Do you have a version that works with SQL Server 2012? It appears that some of the methods have changed.

@Jonesie
Copy link

Jonesie commented Feb 15, 2014

I've forked my conversion for 2012. I also added support for shared datasets and images. https://gist.github.com/Jonesie/9005796

Enjoy!

@timabell
Copy link

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