Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#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
@atchutmca

This comment has been minimized.

Copy link

atchutmca commented Aug 7, 2014

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.

@gep13

This comment has been minimized.

Copy link

gep13 commented Jan 6, 2015

@Jonesie thank you very much for this script, very useful!

@timabell

This comment has been minimized.

Copy link

timabell commented Mar 30, 2015

@edudutra

This comment has been minimized.

Copy link

edudutra commented Feb 25, 2019

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
You can’t perform that action at this time.