-
-
Save jstangroome/3043878 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 |
Hey @kulmam92 and @codeassassin, here's my version which includes two different ways to call it: https://gist.github.com/ChrisMissal/5979564
This is pretty good script. Thanks for sharing.
I think the only thing it lacks is, functionality to deploy Shared Datasets, Is it possible to achieve this via Powershell Script?
Support for shared datasets and 2012. https://gist.github.com/Jonesie/9005796
Hello jstangroome!
Starting from SSRS version 2008 R2 and higher method CreateDataSource returns CatalogItem. Today i've stucked with a problem caused by this, because after invoking $Proxy.CreateDataSource i received duplicated Name and Path from output of New-SSRSDataSource. First entry of this pair was returned by CreateDataSource and second by:
$DataSource = New-Object -TypeName PSObject -Property @{
Name = $Rds.RptDataSource.Name
Path = $Folder + '/' + $Rds.RptDataSource.Name
}. It is not a bug, but more behavior of PowerShell - it concatenated outputs (if they exist).
I've added Out-Null to line 112 and all is Ok now.
Thats why reports with embedded data sources did not deployed.
Thanks a lot for your solution.
Hi, did you write this script yourself? If so are you able to give permission for re-use? Maybe under MIT or something.
full repo for collaboration https://github.com/timabell/ssrs-powershell-deploy
Thanks for sharing good script. Would it be possible to add usage? Do you have any plan to upgrade it for SQL 2012?