ps/Modules/Alkami.DevOps.SqlReports/Public/Set-ReportDataSource.ps1

148 lines
6.3 KiB
PowerShell
Raw Normal View History

2023-05-30 22:51:22 -07:00
function Set-ReportDataSource {
<#
.SYNOPSIS
Set the DataSource for a SSRS report
.PARAMETER Proxy
SSRS Proxy
.PARAMETER ReportPath
Path to report on SSRS server
.PARAMETER RdlPath
Local filepath to RDL report file
.PARAMETER AvoidDoubleHop
Whether to use special measures to avoid the DoubleHop issue
.PARAMETER ReportServerUserName
Username for SSRS server
.PARAMETER ReportServerPassword
Password for SSRS server
#>
[CmdletBinding()]
Param(
[Parameter(Position=0,Mandatory=$true)]
[System.Web.Services.Protocols.SoapHttpClientProtocol]$Proxy,
[Parameter(Position=1, Mandatory=$true)]
[string]$ReportPath,
[Parameter(Position=2, Mandatory=$true)]
[string]$RdlPath,
[Parameter(Position=3, Mandatory=$true)]
[Alias("ApplyDoubleHopFix")]
[bool]$AvoidDoubleHop,
[Parameter(Position=4, Mandatory=$false)]
[Alias("Username")]
[string]$ReportServerUserName,
[Parameter(Position=5, Mandatory=$false)]
[Alias("Password")]
[string]$ReportServerPassword
)
$logLead = Get-LogLeadName
Write-Verbose ("$logLead : Getting XML Datasources of {0}" -f $RdlPath)
[xml]$reportContent = Get-Content $RdlPath
$rdlDataSources = $reportContent.Report.DataSources
Write-Verbose ("$logLead : Getting Datasource References of published report {0} " -f $ReportPath)
$reportDataSources = $Proxy.GetItemDataSources($ReportPath)
Write-Verbose "$logLead : Calling Get-PublishedDataSources"
$publishedDataSources = Get-PublishedDataSources $Proxy ($ReportPath.Split("/") | Where-Object {$_ -ne [String]::Empty} | Select-Object -First 1)
$dirty = $false
foreach ($rdlDataSource in $rdlDataSources.DataSource) {
Write-Verbose ("$logLead : Checking Datasource {0}" -f $rdlDataSource.Name)
$targetDataSource = $reportDataSources | Where-Object {$_.Name -eq $rdlDataSource.Name}
if ($null -eq $targetDataSource) {
Write-Verbose ("$logLead : Unable to find data source in published report with name {0}" -f $rdlDataSource.Name)
continue
}
$ProxyNamespace = $targetDataSource.GetType().Namespace
if ($null -eq $rdlDataSource.DataSourceReference) {
Write-Verbose "$logLead : Setting DataProvider Reference"
$ref = New-Object $targetDataSource.GetType().Assembly.GetType("$Proxynamespace.DataSourceDefinition")
$ref.ConnectString = $rdlDataSource.ConnectionProperties.ConnectString
$ref.Extension = $rdlDataSource.ConnectionProperties.DataProvider
$ref.OriginalConnectStringExpressionBased = ($rdlDataSource.ConnectionProperties.ConnectString -match "^=").ToString()
$ref.Enabled = $true
$ref.EnabledSpecified = $true
$ref.UseOriginalConnectString = $true
$ref.ImpersonateUserSpecified = $true
if ($rdlDataSource.ConnectionProperties.IntegratedSecurity -match "true") {
if ($AvoidDoubleHop) {
# Set the credentials on this data source
if ((Test-IsWebServer) -and ([String]::IsNullOrEmpty($ReportServerUserName) -or [String]::IsNullOrEmpty($ReportServerPassword))) {
# Read the User Credentials from the machine.config
Write-Verbose ("$logLead : Reading Credential Information from the machine.config")
[xml]$config = Get-ReportServerConfiguration
$reportServerUserNode = $config.appSettings.SelectSingleNode("//add[@key=""ReportServerUserName""]/@value")
$ReportServerPasswordNode = $config.appSettings.SelectSingleNode("//add[@key=""ReportServerPassword""]/@value")
if (($null -eq $reportServerUserNode) -or ([String]::IsNullOrEmpty($reportServerUserNode.Value))) {
Write-Warning "$logLead : Could not read the value for the ""ReportServerUserName"" appSetting from the machine.config. Correct this report manually"
return;
}
if (($null -eq $ReportServerPasswordNode) -or ([String]::IsNullOrEmpty($ReportServerPasswordNode.Value))) {
Write-Warning "$logLead : Could not read the value for the ""ReportServerPassword"" appSetting from the machine.config. Correct this report manually"
return;
} else {
Write-Verbose ("$logLead : Using Credentials for $ReportServerUserName Passed via Parameter")
}
$ReportServerUserName = $reportServerUserNode.Value
$ReportServerPassword = $ReportServerPasswordNode.Value
}
Write-Verbose "$logLead : Setting DataSource to Use Username $ReportServerUserName"
$ref.UserName = $ReportServerUserName
$ref.Password = $ReportServerPassword
$ref.WindowsCredentials = $true
}
$ref.CredentialRetrieval = [SSRS.CredentialRetrievalEnum]::Store
}
Write-Host ("$logLead : Setting datasource {0} for report {1} " -f $targetDataSource.Name, $RdlPath)
$targetDataSource.Item = $ref
$dirty = $true
} else {
Write-Verbose "$logLead : Setting DataSource Reference"
$ref = New-Object $targetDataSource.GetType().Assembly.GetType("$Proxynamespace.DataSourceReference")
$ref.Reference = $publishedDataSources | Where-Object {$_.Name -eq $rdlDataSource.Name} | Select-Object -First 1 -ExpandProperty "Path"
if ($ref.Reference.Length -gt 0) {
Write-Verbose ("Setting datasource {0} for report {1} " -f $targetDataSource.Name, $RdlPath)
$targetDataSource.Item = $ref
$dirty = $true
}
}
}
if ($dirty) {
Write-Verbose "$logLead : Saving updated datasources"
try {
$Proxy.SetItemDataSources($ReportPath, $reportDataSources)
} catch [Exception] {
Write-Warning ("$logLead : An invalid parameter was specified for one or more datasources. Correct this report manually. Exception: {0}" -f $_.Exception.Message)
}
}
}