Skip to content

Instantly share code, notes, and snippets.

@Jonesie
Forked from ChrisMissal/Deploy-SSRSProject.ps1
Last active February 25, 2019 18:34
Show Gist options
  • Select an option

  • Save Jonesie/9005796 to your computer and use it in GitHub Desktop.

Select an option

Save Jonesie/9005796 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',
Mandatory=$true)]
[string]
$DataSetFolder,
[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.ReportingService2010.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
}
function New-SSRSDataSet (
$Proxy,
[string]$RsdPath,
[string]$Folder,
[switch]$Overwrite,
$DataSourcePaths
) {
Write-Verbose "New-SSRSDataSet -RsdPath $RsdPath -Folder $Folder"
$Folder = Normalize-SSRSFolder -Folder $Folder
$Name = [System.IO.Path]::GetFileNameWithoutExtension($RsdPath)
$RawDefinition = Get-Content -Encoding Byte -Path $RsdPath
$warnings = $null
$Results = $Proxy.CreateCatalogItem("DataSet", $Name, $Folder, $true, $RawDefinition, $null, [ref]$warnings)
[xml]$Rsd = Get-Content -Path $RsdPath
$DataSourcePath = $DataSourcePaths[$Rsd.SharedDataSet.DataSet.Query.DataSourceReference]
if ($DataSourcePath) {
$Reference = New-Object -TypeName SSRS.ReportingService2010.ItemReference
$Reference.Reference = $DataSourcePath
$Reference.Name = 'DataSetDataSource' #$Rsd.SharedDataSet.DataSet.Name
$Proxy.SetItemReferences($Folder + '/' + $Name, @($Reference))
}
return $Results
}
$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
$DataSetFolder = $Config.DataSetFolder
$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
New-SSRSFolder -Proxy $Proxy -Name $DataSetFolder
$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)
}
$DataSetPaths = @{}
$Project.SelectNodes('Project/DataSets/ProjectItem') |
ForEach-Object {
$RsdPath = $ProjectRoot | Join-Path -ChildPath $_.FullPath
$DataSet = New-SSRSDataSet -Proxy $Proxy -RsdPath $RsdPath -Folder $DataSetFolder -DataSourcePaths $DataSourcePaths
if(-not $DataSetPaths.Contains($DataSet.Name))
{
$DataSetPaths.Add($DataSet.Name, $DataSet.Path)
}
}
$Project.SelectNodes('Project/Reports/ResourceProjectItem') |
ForEach-Object {
if($_.MimeType.StartsWith('image/'))
{
$Path = $ProjectRoot | Join-Path -ChildPath $_.FullPath
$RawDefinition = Get-Content -Encoding Byte -Path $Path
$DescProp = New-Object -TypeName SSRS.ReportingService2010.Property
$DescProp.Name = 'Description'
$DescProp.Value = ''
$HiddenProp = New-Object -TypeName SSRS.ReportingService2010.Property
$HiddenProp.Name = 'Hidden'
$HiddenProp.Value = 'false'
$MimeProp = New-Object -TypeName SSRS.ReportingService2010.Property
$MimeProp.Name = 'MimeType'
$MimeProp.Value = $_.MimeType
$Properties = @($DescProp, $HiddenProp, $MimeProp)
if($_.FullPath.StartsWith('_'))
{
$HiddenProp.Value = 'true'
}
$Name = $_.FullPath
Write-Verbose "Creating resource $Name"
$warnings = $null
$Results = $Proxy.CreateCatalogItem("Resource", $_.FullPath, $Folder, $true, $RawDefinition, $Properties, [ref]$warnings)
}
}
$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$',''
$DescProp = New-Object -TypeName SSRS.ReportingService2010.Property
$DescProp.Name = 'Description'
$DescProp.Value = ''
$HiddenProp = New-Object -TypeName SSRS.ReportingService2010.Property
$HiddenProp.Name = 'Hidden'
$HiddenProp.Value = 'false'
$Properties = @($DescProp, $HiddenProp)
$Xpath = 'd:Report/d:Description'
$DescriptionNode = $Definition.SelectSingleNode($Xpath, $NsMgr)
if($DescriptionNode)
{
$DescProp.Value = $DescriptionNode.Value
}
if($Name.StartsWith('_'))
{
$HiddenProp.Value = 'true'
}
Write-Verbose "Creating report $Name"
$warnings = $null
$Results = $Proxy.CreateCatalogItem("Report", $Name, $Folder, $true, $RawDefinition, $Properties, [ref]$warnings)
$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)
}
$Xpath = 'd:Report/d:DataSets/d:DataSet/d:SharedDataSet/d:SharedDataSetReference/../..'
$References = $Definition.SelectNodes($Xpath, $NsMgr) |
ForEach-Object {
$DataSetPath = $DataSetPaths[$_.SharedDataSet.SharedDataSetReference]
if ($DataSetPath) {
$Reference = New-Object -TypeName SSRS.ReportingService2010.ItemReference
$Reference.Reference = $DataSetPath
$Reference.Name = $_.Name
$Reference
}
}
if ($References) {
$Proxy.SetItemReferences($Folder + '/' + $Name, $References)
}
}
#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
DataSetFolder = Normalize-SSRSFolder -Folder $Config.Options.TargetDataSetFolder
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 += 'ReportService2010.asmx'
}
$Assembly = [AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object {
$_.GetType('SSRS.ReportingService2010.ReportingService2010')
}
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.ReportingService2010 @CredParams
} else {
$Proxy = New-Object -TypeName SSRS.ReportingService2010.ReportingService2010
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
@edudutra
Copy link
Copy Markdown

Great job. Saved me tons of work. Thanks

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