Last active
August 28, 2024 05:58
-
-
Save EitanBlumin/e3b34d4c2de793054854e0e3d43f4349 to your computer and use it in GitHub Desktop.
Powershell script to deploy SSRS reports from a folder (all rds and rdl files)
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
Param | |
( | |
[string] $SourceFolder = "C:\SSRS\My-Reports", | |
[string] $TargetReportServerUri = "http://localhost:8081/ReportServer", | |
[PSCredential] $Credential, | |
[switch] $CustomAuthentication, | |
[string] $ApiVersion, | |
[string] $TargetFolder = "/My-Reports/Sample-Reports", | |
[switch] $Recursive, | |
[string] $OverrideDataSourcePathForAll, #= "/My-Reports/Data Sources/ProdDS", | |
[string] $logFileFolderPath = "C:\SSRS_deployment_log", | |
[string] $logFilePrefix = "ssrs_deploy_", | |
[string] $logFileDateFormat = "yyyyMMdd_HHmmss", | |
[int] $logFileRetentionDays = 30 | |
) | |
Process { | |
#region initialization | |
function Get-TimeStamp { | |
Param( | |
[switch]$NoWrap, | |
[switch]$Utc | |
) | |
$dt = Get-Date | |
if ($Utc -eq $true) { | |
$dt = $dt.ToUniversalTime() | |
} | |
$str = "{0:MM/dd/yy} {0:HH:mm:ss}" -f $dt | |
if ($NoWrap -ne $true) { | |
$str = "[$str]" | |
} | |
return $str | |
} | |
if ($logFileFolderPath -ne "") | |
{ | |
if (!(Test-Path -PathType Container -Path $logFileFolderPath)) { | |
Write-Output "$(Get-TimeStamp) Creating directory $logFileFolderPath" | Out-Null | |
New-Item -ItemType Directory -Force -Path $logFileFolderPath | Out-Null | |
} else { | |
$DatetoDelete = $(Get-Date).AddDays(-$logFileRetentionDays) | |
Get-ChildItem $logFileFolderPath | Where-Object { $_.Name -like "*$logFilePrefix*" -and $_.LastWriteTime -lt $DatetoDelete } | Remove-Item | Out-Null | |
} | |
$logFilePath = $logFileFolderPath + "\$logFilePrefix" + (Get-Date -Format $logFileDateFormat) + ".LOG" | |
# attempt to start the transcript log, but don't fail the script if unsuccessful: | |
try | |
{ | |
Start-Transcript -Path $logFilePath -Append | |
} | |
catch [Exception] | |
{ | |
Write-Warning "$(Get-TimeStamp) Unable to start Transcript: $($_.Exception.Message)" | |
$logFileFolderPath = "" | |
} | |
} | |
#endregion initialization | |
#region install-modules | |
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | |
if (Get-PSRepository -Name "PSGallery") { | |
Write-Verbose "$(Get-TimeStamp) PSGallery already registered" | |
} | |
else { | |
Write-Information "$(Get-TimeStamp) Registering PSGallery" | |
Register-PSRepository -Default | |
} | |
if (Get-Module -ListAvailable -Name PowerShellGet) { | |
Write-Verbose "$(Get-TimeStamp) PowerShellGet already installed" | |
} | |
else { | |
Write-Information "$(Get-TimeStamp) Installing PowerShellGet" | |
Install-Module PowerShellGet -RequiredVersion 2.2.4 -Force -SkipPublisherCheck -Scope CurrentUser -ErrorAction Stop -AllowClobber | Out-Null | |
Import-Module PowerShellGet -Force -Scope Local | Out-Null | |
} | |
if ((Get-PSRepository -Name "PSGallery").Trusted) { | |
Write-Verbose "$(Get-TimeStamp) PSGallery already Trusted" | |
} else { | |
Write-Information "$(Get-TimeStamp) Marking PSGallery as Trusted..." | |
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted | |
} | |
# replace the array below with any modules that your script depends on. | |
# you can remove this region if your script doesn't need importing any modules. | |
$modules = @("ReportingServicesTools") | |
foreach ($module in $modules) { | |
if (Get-Module -ListAvailable -Name $module) { | |
Write-Verbose "$(Get-TimeStamp) $module already installed" | |
} | |
else { | |
Write-Information "$(Get-TimeStamp) Installing $module" | |
Install-Module $module -Force -SkipPublisherCheck -Scope CurrentUser -ErrorAction Stop | Out-Null | |
Import-Module $module -Force -Scope Local | Out-Null | |
} | |
} | |
#Write-Output "Requesting RSTools..." | |
#Invoke-Expression (Invoke-WebRequest https://aka.ms/rstools) | |
#endregion install-modules | |
#region main | |
$ErrorActionPreference = "Stop" | |
if ($SourceFolder -eq "" -or $SourceFolder -eq $null) { | |
$SourceFolder = $(Get-Location).Path + "\" | |
} | |
if ($TargetFolder -eq "" -or $TargetFolder -eq $null) { | |
$TargetFolder = "/" | |
} | |
if (!$SourceFolder.EndsWith("\")) | |
{ | |
$SourceFolder = $SourceFolder + "\" | |
} | |
Write-Output "=====================================================================================" | |
Write-Output " Deploying SSRS Reports" | |
Write-Output "Target Server: $TargetReportServerUri" | |
$ProxyParams = @{ | |
ReportServerUri = $TargetReportServerUri | |
CustomAuthentication = $CustomAuthentication | |
} | |
if ($Credential -ne $null) { | |
Write-Output "Username: $($Credential.UserName)" | |
$ProxyParams.Credential = $Credential | |
} | |
if ($ApiVersion -ne $null) { | |
Write-Output "ApiVersion: $ApiVersion" | |
$ProxyParams.ApiVersion = $ApiVersion | |
} | |
Write-Output "=====================================================================================" | |
$Proxy = New-RsWebServiceProxy @ProxyParams | |
$SourceFoldersList = @() | |
$SourceFoldersList += $SourceFolder | |
if ($Recursive) { | |
Get-ChildItem -Recurse -Directory -Path $SourceFolder | ForEach-Object { | |
$SourceFoldersList += $_.FullName | |
} | |
} | |
$SourceFoldersList | ForEach-Object { | |
$currSourceFolder = $_ | |
if (!$currSourceFolder.EndsWith("\")) | |
{ | |
$currSourceFolder = $currSourceFolder + "\" | |
} | |
if ($currSourceFolder -ne $SourceFolder) { | |
$currTargetFolder = $TargetFolder + "/" + [Regex]::Replace($currSourceFolder,$SourceFolder.Replace('\','\\'),'').Replace('\','/') | |
} else { | |
$currTargetFolder = $TargetFolder | |
} | |
Write-Output "=====================================================================================" | |
Write-Output "Source Folder: $currSourceFolder" | |
Write-Output "Target Folder: $currTargetFolder" | |
Write-Output "==============" | |
if ($currTargetFolder -ne "/") { | |
if ($currTargetFolder.StartsWith("/")) { | |
$currTargetFolder = $currTargetFolder.Remove(0,1) | |
} | |
Write-Output "$(Get-TimeStamp) Creating Folder: $currTargetFolder" | |
New-RsFolder -Proxy $Proxy -Path / -Name $currTargetFolder -Verbose -ErrorAction SilentlyContinue | |
} | |
if (!$currTargetFolder.StartsWith("/")) { | |
$currTargetFolder = $currTargetFolder.Insert(0, "/") | |
} | |
Write-Output "$(Get-TimeStamp) Deploying Data Source files from: $currSourceFolder" | |
DIR $currSourceFolder -Filter *.rds | % { $_.FullName } | Write-RsCatalogItem -Proxy $Proxy -Destination $currTargetFolder -Verbose -Overwrite | |
Write-Output "$(Get-TimeStamp) Deploying Data Set files from: $currSourceFolder" | |
DIR $currSourceFolder -Filter *.rsd | % { $_.FullName } | Write-RsCatalogItem -Proxy $Proxy -Destination $currTargetFolder -Verbose -Overwrite | |
Write-Output "$(Get-TimeStamp) Deploying Report Definition files from: $currSourceFolder" | |
DIR $currSourceFolder -Filter *.rdl | % { $_.FullName } | Write-RsCatalogItem -Proxy $Proxy -Destination $currTargetFolder -Verbose -Overwrite | |
if ($OverrideDataSourcePathForAll -ne $null -and $OverrideDataSourcePathForAll -ne "") { | |
Write-Output "$(Get-TimeStamp) Fixing Data Source references to: $OverrideDataSourcePathForAll" | |
Get-RsFolderContent -Proxy $Proxy -RsFolder $currTargetFolder | ForEach { | |
$CurrReport = $_ | |
Get-RsItemReference -Proxy $Proxy -Path $CurrReport.Path | Where ReferenceType -eq "DataSource" | ForEach { | |
$CurrReference = $_ | |
if ($CurrReference.Reference -ne $OverrideDataSourcePathForAll) { | |
Write-Output "$(Get-TimeStamp) UPDATING: Data Source $($CurrReference.Name) in report $($CurrReport.Path)" | |
Set-RsDataSourceReference -Proxy $Proxy -Path $CurrReport.Path -DataSourceName $CurrReference.Name -DataSourcePath $OverrideDataSourcePathForAll | |
} else { | |
Write-Output "$(Get-TimeStamp) Data Source $($CurrReference.Name) in report $($CurrReport.Path) already set correctly." | |
} | |
} | |
} | |
} | |
} | |
#endregion main | |
#region finalization | |
if ($logFileFolderPath -ne "") { Stop-Transcript } | |
#endregion finalization | |
} |
Hi @kadiyala82 .
Based on your error, it looks like you specified an empty string for the ApiVersion
parameter.
It should be $null
or unspecified instead.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello EItanBlumin
First of all thanks for replying. I just used the updated script, but I got below error.
Target Server:
ApiVersion:
PS>TerminatingError(New-RsWebServiceProxy): "Cannot validate argument on parameter 'ApiVersion'. The argument "" does not belong to the set "2005,2006,2010" specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again."