Skip to content
Open
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vs/
ssrs-powershell-deploy/obj/
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ parameters.
Publish-SSRSProject [-Path] <string> [[-Configuration]
<string>] [[-ServerUrl] <string>] [[-Folder] <string>]
[[-DataSourceFolder] <string>] [[-DataSetFolder] <string>]
[[-OutputPath] <string>] [[-OverwriteDataSources] <bool>]
[[-OverwriteDatasets] <bool>] [[-Credential] <pscredential>]
[[-OutputPath] <string>]
[[-OverwriteDataSources] <bool>] [[-OverwriteDatasets] <bool>]
[[-Credential] <pscredential>] [-CustomAuthentication]
[<CommonParameters>]

## Example reports
Expand Down
22 changes: 7 additions & 15 deletions ssrs-powershell-deploy/SSRS/Get-SSRSProjectConfiguration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,25 @@
Write-Verbose "Reading '$Configuration' config from '$Path'"

[xml]$Project = Get-Content -Path $Path
$Namespace = New-Object Xml.XmlNamespaceManager $Project.NameTable
$Namespace.AddNamespace('ns', $Project.DocumentElement.NamespaceURI)

$propertyGroupCount = $Project.Project.PropertyGroup.Count
$Config = $Project.SelectNodes('//ns:PropertyGroup', $Namespace) |
Where-Object { $_.FullPath -eq $Configuration } |
Select-Object -First 1

for($i = 0; $i -lt $propertyGroupCount; $i++)
{
if($Project.Project.PropertyGroup[$i].FullPath -eq $Configuration)
{
$Config = $Project.Project.PropertyGroup[$i]
break
}
}

#$Config = $Project.SelectNodes('Project/PropertyGroup') |
# Where-Object { $_.FullPath -eq $Configuration } |
# Select-Object -First 1
if (-not $Config) {
throw "Could not find configuration '$Configuration'."
}


$OverwriteDataSources = $false
if ($Config.SelectSingleNode('OverwriteDataSources')) {
if ($Config.SelectSingleNode('ns:OverwriteDataSources', $Namespace)) {
$OverwriteDataSources = [Convert]::ToBoolean($Config.OverwriteDataSources)
}

$OverwriteDatasets = $false
if ($Config.SelectSingleNode('OverwriteDatasets')) {
if ($Config.SelectSingleNode('ns:OverwriteDatasets', $Namespace)) {
$OverwriteDatasets = [Convert]::ToBoolean($Config.OverwriteDatasets)
}

Expand Down
6 changes: 6 additions & 0 deletions ssrs-powershell-deploy/SSRS/New-SSRSDataSource.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ function New-SSRSDataSource (
$Definition.ConnectString = $ConnProps.ConnectString
$Definition.Extension = $ConnProps.Extension

$connectionString = New-Object System.Data.Common.DbConnectionStringBuilder
$connectionString.set_ConnectionString($ConnProps.ConnectString)

#Does the IntegratedSecurity property exist
$integratedproperty = $ConnProps | Get-Member -MemberType Property | where {$_.name -like 'IntegratedSecurity'}
Expand All @@ -31,6 +33,10 @@ function New-SSRSDataSource (
}
else{
write-verbose "IntegratedSecurity Missing"

$Definition.CredentialRetrieval = 'Store'
$Definition.UserName = $connectionString['User ID']
$Definition.Password = $connectionString['Password']
}

$DataSource = New-Object -TypeName PSObject -Property @{
Expand Down
78 changes: 78 additions & 0 deletions ssrs-powershell-deploy/SSRS/New-SSRSFolder.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,82 @@ function New-SSRSFolder (
Write-Verbose " - skipped, already exists"
}
}

$type = $Proxy.GetType().Namespace;
$policyType = "{0}.Policy" -f $type;
$roleType = "{0}.Role" -f $type;

$InheritParent = $true

if($Name -eq '/Core' -or $Name -eq '/Client_Data' -or $Name -eq '/Import' -or $Name -eq '/Datasets')
{
Write-Verbose "Setting Policies for Subscribers..."

$Policies = $Proxy.GetPolicies($Name, [ref]$InheritParent)

$GroupUserName = 'Subscribers'
$RoleName = 'Browser'

#Return all policies that contain the user/group we want to add
$Policy = $Policies |
Where-Object { $_.GroupUserName -eq $GroupUserName } |
Select-Object -First 1
#Add a new policy if doesnt exist
if (-not $Policy)
{
$Policy = New-Object ($policyType)
$Policy.GroupUserName = $GroupUserName
$Policy.Roles = @()
#Add new policy to the folder's policies
$Policies += $Policy
}
#Add the role to the new Policy
$r = $Policy.Roles |
Where-Object { $_.Name -eq $RoleName } |
Select-Object -First 1
if (-not $r)
{
$r = New-Object ($roleType)
$r.Name = $RoleName
$Policy.Roles += $r
}

#Set folder policies
$Proxy.SetPolicies($Name, $Policies);
}

Write-Verbose "Setting Policies for Administrators..."

$Policies = $Proxy.GetPolicies('/', [ref]$InheritParent)

#Admin
$GroupUserName = 'Administrators'
$RoleName = 'Content Manager'

#Return all policies that contain the user/group we want to add
$Policy = $Policies |
Where-Object { $_.GroupUserName -eq $GroupUserName } |
Select-Object -First 1
#Add a new policy if doesnt exist
if (-not $Policy)
{
$Policy = New-Object ($policyType)
$Policy.GroupUserName = $GroupUserName
$Policy.Roles = @()
#Add new policy to the folder's policies
$Policies += $Policy
}
#Add the role to the new Policy
$r = $Policy.Roles |
Where-Object { $_.Name -eq $RoleName } |
Select-Object -First 1
if (-not $r)
{
$r = New-Object ($roleType)
$r.Name = $RoleName
$Policy.Roles += $r
}

#Set folder policies
$Proxy.SetPolicies('/', $Policies);
}
26 changes: 25 additions & 1 deletion ssrs-powershell-deploy/SSRS/New-SSRSWebServiceProxy.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
$Uri,

[System.Management.Automation.PSCredential]
$Credential
$Credential,

[parameter(Mandatory=$false)]
[switch]
$CustomAuthentication
)

$script:ErrorActionPreference = 'Stop'
Expand Down Expand Up @@ -51,5 +55,25 @@
}

$Proxy.Url = $Uri

Write-Verbose "Custom Authentication: $CustomAuthentication"

if ($CustomAuthentication)
{
if (!$Credential)
{
$Credential = Get-Credential
}

$NetworkCredential = $Credential.GetNetworkCredential()
$proxy.CookieContainer = New-Object System.Net.CookieContainer

Write-Verbose "Logging in..."

$Proxy.LogonUser($NetworkCredential.UserName, $NetworkCredential.Password, $NetworkCredential.Domain);

Write-Verbose "Authenticated!"
}

return $Proxy
}
89 changes: 44 additions & 45 deletions ssrs-powershell-deploy/SSRS/Publish-SSRSProject.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@
[bool]
$OverwriteDatasets, #THESE ARE NOW OVERRRIDES IF $Configuration is specified


[System.Management.Automation.PSCredential]
$Credential
$Credential,

[parameter(Mandatory=$false)]
[switch]
$CustomAuthentication
)


Expand All @@ -55,7 +58,8 @@
$ProjectRoot = $Path | Split-Path
[xml]$Project = Get-Content -Path $Path


$Namespace = New-Object Xml.XmlNamespaceManager $Project.NameTable
$Namespace.AddNamespace('ns', $Project.DocumentElement.NamespaceURI)

#Argument validation
if(![string]::IsNullOrEmpty($Configuration))
Expand Down Expand Up @@ -107,10 +111,11 @@

}

$Project.SelectNodes('Project/Reports/ProjectItem') |
$Project.SelectNodes('//ns:Report', $Namespace) |
ForEach-Object {
$CompiledRdlPath = $ProjectRoot | Join-Path -ChildPath $OutputPath | join-path -ChildPath $_.FullPath
$RdlPath = $ProjectRoot | join-path -ChildPath $_.FullPath
$Name = $_.Include
$CompiledRdlPath = $ProjectRoot | Join-Path -ChildPath $OutputPath | join-path -ChildPath $Name
$RdlPath = $ProjectRoot | join-path -ChildPath $Name

if ((test-path $CompiledRdlPath) -eq $false)
{
Expand All @@ -130,41 +135,51 @@
$Folder = Normalize-SSRSFolder -Folder $Folder
$DataSourceFolder = Normalize-SSRSFolder -Folder $DataSourceFolder

$Proxy = New-SSRSWebServiceProxy -Uri $ServerUrl -Credential $Credential
$ProxyParameters = @{
Uri = $ServerUrl
Credential = $Credential
CustomAuthentication = $CustomAuthentication
}

Write-Verbose "Connecting to: $ServerUrl"

$Proxy = New-SSRSWebServiceProxy @ProxyParameters
$FullServerPath = $Proxy.Url
Write-Verbose "Connecting to: $FullServerPath"

New-SSRSFolder -Proxy $Proxy -Name $Folder
New-SSRSFolder -Proxy $Proxy -Name $DataSourceFolder
New-SSRSFolder -Proxy $Proxy -Name $DataSetFolder

$DataSourcePaths = @{}
for($i = 0; $i -lt $Project.Project.ItemGroup[0].DataSource.Count; $i++) {
$RdsPath = $ProjectRoot | Join-Path -ChildPath $Project.Project.ItemGroup[0].DataSource[$i].Include
$Project.SelectNodes('//ns:DataSource', $Namespace) |
ForEach-Object {
$Name = $_.Include
$RdsPath = $ProjectRoot | Join-Path -ChildPath $Name

$DataSource = New-SSRSDataSource -Proxy $Proxy -RdsPath $RdsPath -Folder $DataSourceFolder -Overwrite $OverwriteDataSources
$DataSourcePaths.Add($DataSource.Name, $DataSource.Path)
}
$DataSource = New-SSRSDataSource -Proxy $Proxy -RdsPath $RdsPath -Folder $DataSourceFolder -Overwrite $OverwriteDataSources
$DataSourcePaths.Add($DataSource.Name, $DataSource.Path)
}

$DataSetPaths = @{}
$Project.SelectNodes('Project/DataSets/ProjectItem') |
$Project.SelectNodes('//ns:DataSet', $Namespace) |
ForEach-Object {
$RsdPath = $ProjectRoot | Join-Path -ChildPath $_.FullPath
$Name = $_.Include
$RsdPath = $ProjectRoot | Join-Path -ChildPath $Name
$DataSet = New-SSRSDataSet -Proxy $Proxy -RsdPath $RsdPath -Folder $DataSetFolder -DataSourcePaths $DataSourcePaths -Overwrite $OverwriteDatasets
if(-not $DataSetPaths.Contains($DataSet.Name))
{
$DataSetPaths.Add($DataSet.Name, $DataSet.Path)
}
}

for($i = 0; $i -lt $Project.Project.ItemGroup[1].Report.Count; $i++) {

$extension = $Project.Project.ItemGroup[1].Report[$i].Include.Substring($Project.Project.ItemGroup[1].Report[$i].Include.length - 3 , 3)
$Project.SelectNodes('//ns:Report', $Namespace) |
ForEach-Object {
$Name = $_.Include
$MimeType = $_.SelectSingleNode('ns:MimeType', $Namespace)

if(ImageExtensionValid -ext $extension){
if($MimeType){

$PathImage = $ProjectRoot | Join-Path -ChildPath $Project.Project.ItemGroup[1].Report[$i].Include
$PathImage = $ProjectRoot | Join-Path -ChildPath $Name
$RawDefinition = Get-Content -Encoding Byte -Path $PathImage

$DescProp = New-Object -TypeName SSRS.ReportingService2010.Property
Expand All @@ -175,37 +190,21 @@
$HiddenProp.Value = 'false'
$MimeProp = New-Object -TypeName SSRS.ReportingService2010.Property
$MimeProp.Name = 'MimeType'
$MimeProp.Value = 'image/' + $extension
$MimeProp.Value = $MimeType

$Properties = @($DescProp, $HiddenProp, $MimeProp)

$Name = $Project.Project.ItemGroup[1].Report[$i].Include
$Name = $Name
Write-Verbose "Creating resource $Name"
$warnings = $null
$Results = $Proxy.CreateCatalogItem("Resource", $Project.Project.ItemGroup[1].Report[$i].Include, $Folder, $true, $RawDefinition, $Properties, [ref]$warnings)
$Results = $Proxy.CreateCatalogItem("Resource", $Name, $Folder, $true, $RawDefinition, $Properties, [ref]$warnings)
}

if($Name.EndsWith('.rdl')){
$CompiledRdlPath = $ProjectRoot | Join-Path -ChildPath $OutputPath | join-path -ChildPath $Name
New-SSRSReport -Proxy $Proxy -RdlPath $CompiledRdlPath -RdlName $Name
}
}

for($i = 0; $i -lt $Project.Project.ItemGroup[1].Report.Count; $i++) {
if($Project.Project.ItemGroup[1].Report[$i].Include.EndsWith('.rdl')){
$CompiledRdlPath = $ProjectRoot | Join-Path -ChildPath $OutputPath | join-path -ChildPath $Project.Project.ItemGroup[1].Report[$i].Include
New-SSRSReport -Proxy $Proxy -RdlPath $CompiledRdlPath -RdlName $Project.Project.ItemGroup[1].Report[$i].Include
}
}

Write-host "Completed."
}

function ImageExtensionValid($ext){
$valid = 0;

Switch($ext)
{
'png' { $valid = 1; }
'bmp' { $valid = 1; }
'gif' { $valid = 1; }
'jpg' { $valid = 1; }
}

return $valid;
Write-host "Completed: $Path"
}
16 changes: 14 additions & 2 deletions ssrs-powershell-deploy/SSRS/Publish-SSRSSolution.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ function Publish-SSRSSolution{
$Configuration,

[System.Management.Automation.PSCredential]
$credentials
$credentials,

[parameter(Mandatory=$false)]
[switch]
$CustomAuthentication
)

$ErrorActionPreference = 'Stop'
Expand Down Expand Up @@ -48,7 +52,15 @@ function Publish-SSRSSolution{
$ProjectPath = ($ProjectPath | Resolve-Path).ProviderPath
#"$ProjectPath" = full path to the project file

& Publish-SSRSProject -path $ProjectPath -configuration $configuration -verbose -credential $credentials
$ProjectParameters = @{
Path = $ProjectPath
Configuration = $configuration
Credential = $credentials
Verbose = $true
CustomAuthentication = $CustomAuthentication
}

& Publish-SSRSProject @ProjectParameters
}
}

Expand Down