Forked from ChrisMissal/Deploy-SSRSProject.ps1
Last active
February 25, 2019 18:34
-
-
Save Jonesie/9005796 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$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 |
@Jonesie thank you very much for this script, very useful!
full repo for collaboration https://github.com/timabell/ssrs-powershell-deploy
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
Hi,
Could you please give me an example of the command to deploy? I have tried following but not successful.
$pass = ConvertTo-SecureString -AsPlainText -Force -String "password-of-the-user"
$user = "windows-user-of-the-windows-computer-on-which-the-ssrs-report-created"
.\Deploy-SSRSProject.ps1 -Verbose -Path 'C:\Users\username\Documents\Visual Studio 2008\Projects\Report Project2\Report Project2\Report Project2.rptproj' -Configuration 'windows-computer-name-on-which-the-report-project-is-created' -Credential $cred
Thanks & Regards,
Atchut.