Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added public command `Get-SqlDscRSPackage` to retrieve package information for
SQL Server Reporting Services or Power BI Report Server. Supports getting version
information from an installed package or from an executable file
([issue #2082](https://github.com/dsccommunity/SqlServerDsc/issues/2082)).
- Added public command `Get-SqlDscBackupFileList` to read the list of database
files contained in a SQL Server backup file. Useful for planning file
relocations during restore operations ([issue #2026](https://github.com/dsccommunity/SqlServerDsc/issues/2026)).
Expand Down
2 changes: 2 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ stages:
'tests/Integration/Commands/Install-SqlDscReportingService.Integration.Tests.ps1'
# Group 2
'tests/Integration/Commands/Get-SqlDscInstalledInstance.Integration.Tests.ps1'
'tests/Integration/Commands/Get-SqlDscRSPackage.Integration.Tests.ps1'
'tests/Integration/Commands/Get-SqlDscRSSetupConfiguration.Integration.Tests.ps1'
'tests/Integration/Commands/Test-SqlDscRSInstalled.Integration.Tests.ps1'
# Group 8
Expand Down Expand Up @@ -596,6 +597,7 @@ stages:
'tests/Integration/Commands/Install-SqlDscPowerBIReportServer.Integration.Tests.ps1'
# Group 2
'tests/Integration/Commands/Get-SqlDscInstalledInstance.Integration.Tests.ps1'
'tests/Integration/Commands/Get-SqlDscRSPackage.Integration.Tests.ps1'
'tests/Integration/Commands/Get-SqlDscRSSetupConfiguration.Integration.Tests.ps1'
'tests/Integration/Commands/Test-SqlDscRSInstalled.Integration.Tests.ps1'
# Group 8
Expand Down
162 changes: 162 additions & 0 deletions source/Public/Get-SqlDscRSPackage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<#
.SYNOPSIS
Gets package information for SQL Server Reporting Services or Power BI
Report Server.

.DESCRIPTION
Gets package information for an installed SQL Server Reporting Services or
Power BI Report Server package, or from a setup executable file. The command
returns file version information including product name, product version,
file version, and other version-related metadata.

When using the `Package` parameter, the command retrieves the installed
package executable and returns its version information.

When using the `FilePath` parameter, the command returns version information
from the specified executable file.

.PARAMETER Package
Specifies if either the Reporting Services or Power BI Report Server package
should be retrieved. Valid values are 'SSRS' and 'PBIRS'.

.PARAMETER FilePath
Specifies the path to the executable file to return version information for.
The file must have a product name matching either 'Microsoft SQL Server
Reporting Services' or 'Microsoft Power BI Report Server'.

.PARAMETER Force
If specified, the ProductName validation is skipped when using the FilePath
parameter. This allows retrieving version information for executables with
different product names.

.EXAMPLE
Get-SqlDscRSPackage -Package 'SSRS'

Returns package information for the installed SQL Server Reporting Services
package.

.EXAMPLE
Get-SqlDscRSPackage -Package 'PBIRS'

Returns package information for the installed Power BI Report Server package.

.EXAMPLE
Get-SqlDscRSPackage -FilePath 'E:\SQLServerReportingServices.exe'

Returns package information from the specified SQL Server Reporting Services
executable file.

.EXAMPLE
Get-SqlDscRSPackage -FilePath 'E:\PBIReportServer.exe'

Returns package information from the specified Power BI Report Server
executable file.

.EXAMPLE
Get-SqlDscRSPackage -FilePath 'E:\CustomReportServer.exe' -Force

Returns package information from the specified executable file without
validating the product name.

.INPUTS
None.

.OUTPUTS
`System.Diagnostics.FileVersionInfo`

Returns the file version information for the package.
#>
function Get-SqlDscRSPackage
{
# cSpell: ignore PBIRS
[CmdletBinding(DefaultParameterSetName = 'Package')]
[OutputType([System.Diagnostics.FileVersionInfo])]
param
(
[Parameter(Mandatory = $true, ParameterSetName = 'Package')]
[ValidateSet('SSRS', 'PBIRS')]
[System.String]
$Package,

[Parameter(Mandatory = $true, ParameterSetName = 'FilePath')]
[System.String]
$FilePath,

[Parameter(ParameterSetName = 'FilePath')]
[System.Management.Automation.SwitchParameter]
$Force
)

$versionInfo = $null
$validProductNames = @(
'Microsoft SQL Server Reporting Services'
'Microsoft Power BI Report Server'
)

if ($PSCmdlet.ParameterSetName -eq 'Package')
{
Write-Debug -Message ($script:localizedData.Get_SqlDscRSPackage_GettingInstalledPackage -f $Package)

$rsSetupConfiguration = Get-SqlDscRSSetupConfiguration -InstanceName $Package -ErrorAction 'SilentlyContinue'

if (-not $rsSetupConfiguration)
{
$errorMessage = $script:localizedData.Get_SqlDscRSPackage_PackageNotFound -f $Package

$PSCmdlet.ThrowTerminatingError(
[System.Management.Automation.ErrorRecord]::new(
$errorMessage,
'GSDRSP0001',
[System.Management.Automation.ErrorCategory]::ObjectNotFound,
$Package
)
)
}

$installFolder = $rsSetupConfiguration.InstallFolder

Write-Debug -Message ($script:localizedData.Get_SqlDscRSPackage_FoundInstallFolder -f $installFolder)

# Determine the executable name based on package type
if ($Package -eq 'SSRS')
{
$executablePath = Join-Path -Path $installFolder -ChildPath 'RSHostingService\ReportingServicesService.exe'
}
else
{
# PBIRS
$executablePath = Join-Path -Path $installFolder -ChildPath 'RSHostingService\ReportingServicesService.exe'
}

Write-Debug -Message ($script:localizedData.Get_SqlDscRSPackage_GettingVersionInfo -f $executablePath)

$versionInfo = Get-FileVersion -Path $executablePath
}
else
{
Write-Debug -Message ($script:localizedData.Get_SqlDscRSPackage_GettingVersionFromFile -f $FilePath)

$versionInfo = Get-FileVersion -Path $FilePath

if (-not $Force.IsPresent)
{
if ($versionInfo.ProductName -notin $validProductNames)
{
$errorMessage = $script:localizedData.Get_SqlDscRSPackage_InvalidProductName -f $versionInfo.ProductName, ($validProductNames -join "', '")

$PSCmdlet.ThrowTerminatingError(
[System.Management.Automation.ErrorRecord]::new(
$errorMessage,
'GSDRSP0002',
[System.Management.Automation.ErrorCategory]::InvalidArgument,
$FilePath
)
)
}
}
}

Write-Debug -Message ($script:localizedData.Get_SqlDscRSPackage_ReturningVersionInfo -f $versionInfo.ProductName, $versionInfo.ProductVersion)

return $versionInfo
}
9 changes: 9 additions & 0 deletions source/en-US/SqlServerDsc.strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -662,4 +662,13 @@ ConvertFrom-StringData @'
## Get-SqlDscDateTime
Get_SqlDscDateTime_RetrievingDateTime = Retrieving date and time using {0}(). (GSDD0001)
Get_SqlDscDateTime_FailedToRetrieve = Failed to retrieve date and time using {0}(): {1} (GSDD0002)

## Get-SqlDscRSPackage
Get_SqlDscRSPackage_GettingInstalledPackage = Getting installed package information for '{0}'. (GSDRSP0003)
Get_SqlDscRSPackage_PackageNotFound = The package '{0}' was not found. Ensure that the package is installed. (GSDRSP0001)
Get_SqlDscRSPackage_FoundInstallFolder = Found install folder '{0}'. (GSDRSP0004)
Get_SqlDscRSPackage_GettingVersionInfo = Getting version information from '{0}'. (GSDRSP0005)
Get_SqlDscRSPackage_GettingVersionFromFile = Getting version information from file '{0}'. (GSDRSP0006)
Get_SqlDscRSPackage_InvalidProductName = The product name '{0}' is not a valid Reporting Services package. Expected product names are: '{1}'. Use the Force parameter to skip this validation. (GSDRSP0002)
Get_SqlDscRSPackage_ReturningVersionInfo = Returning version information for '{0}' version '{1}'. (GSDRSP0007)
'@
132 changes: 132 additions & 0 deletions tests/Integration/Commands/Get-SqlDscRSPackage.Integration.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]
param ()

BeforeDiscovery {
try
{
if (-not (Get-Module -Name 'DscResource.Test'))
{
# Assumes dependencies have been resolved, so if this module is not available, run 'noop' task.
if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable))
{
# Redirect all streams to $null, except the error stream (stream 2)
& "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 3>&1 4>&1 5>&1 6>&1 > $null
}

# If the dependencies have not been resolved, this will throw an error.
Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop'
}
}
catch [System.IO.FileNotFoundException]
{
throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks noop" first.'
}
}

BeforeAll {
$script:moduleName = 'SqlServerDsc'

Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop'
}

Describe 'Get-SqlDscRSPackage' {
Context 'When getting package information for SQL Server Reporting Services' -Tag @('Integration_SQL2017_RS', 'Integration_SQL2019_RS', 'Integration_SQL2022_RS') {
It 'Should return the package information for SSRS' {
$result = Get-SqlDscRSPackage -Package 'SSRS' -ErrorAction 'Stop'

$result | Should -Not -BeNullOrEmpty
$result.ProductName | Should -Be 'Microsoft SQL Server Reporting Services'
$result.FileVersion | Should -Not -BeNullOrEmpty
$result.ProductVersion | Should -Not -BeNullOrEmpty
}

It 'Should return the same result when using FilePath parameter' {
# Get the install folder from the setup configuration
$setupConfig = Get-SqlDscRSSetupConfiguration -InstanceName 'SSRS' -ErrorAction 'Stop'

$executablePath = Join-Path -Path $setupConfig.InstallFolder -ChildPath 'RSHostingService/ReportingServicesService.exe'

$result = Get-SqlDscRSPackage -FilePath $executablePath -ErrorAction 'Stop'

$result | Should -Not -BeNullOrEmpty
$result.ProductName | Should -Be 'Microsoft SQL Server Reporting Services'
$result.FileVersion | Should -Not -BeNullOrEmpty
$result.ProductVersion | Should -Not -BeNullOrEmpty
}
}

Context 'When getting package information for Power BI Report Server' -Tag @('Integration_PowerBI') {
# cSpell: ignore PBIRS
It 'Should return the package information for PBIRS' {
$result = Get-SqlDscRSPackage -Package 'PBIRS' -ErrorAction 'Stop'

$result | Should -Not -BeNullOrEmpty
$result.ProductName | Should -Be 'Microsoft Power BI Report Server'
$result.FileVersion | Should -Not -BeNullOrEmpty
$result.ProductVersion | Should -Not -BeNullOrEmpty
}

It 'Should return the same result when using FilePath parameter' {
# Get the install folder from the setup configuration
$setupConfig = Get-SqlDscRSSetupConfiguration -InstanceName 'PBIRS' -ErrorAction 'Stop'

$executablePath = Join-Path -Path $setupConfig.InstallFolder -ChildPath 'RSHostingService/ReportingServicesService.exe'

$result = Get-SqlDscRSPackage -FilePath $executablePath -ErrorAction 'Stop'

$result | Should -Not -BeNullOrEmpty
$result.ProductName | Should -Be 'Microsoft Power BI Report Server'
$result.FileVersion | Should -Not -BeNullOrEmpty
$result.ProductVersion | Should -Not -BeNullOrEmpty
}
}

Context 'When getting package information for a non-existing package' -Tag @('Integration_SQL2017_RS', 'Integration_SQL2019_RS', 'Integration_SQL2022_RS', 'Integration_PowerBI') {
It 'Should throw an error when the package is not installed' {
# PBIRS is not installed in the SSRS CI environment and vice versa
# We can test this by checking which one is installed
$ssrsInstalled = Test-SqlDscRSInstalled -InstanceName 'SSRS'

if ($ssrsInstalled)
{
# SSRS is installed, so PBIRS should not be
{ Get-SqlDscRSPackage -Package 'PBIRS' -ErrorAction 'Stop' } | Should -Throw
}
else
{
# PBIRS is installed, so SSRS should not be
{ Get-SqlDscRSPackage -Package 'SSRS' -ErrorAction 'Stop' } | Should -Throw
}
}
}

Context 'When using Force parameter to bypass validation' -Tag @('Integration_SQL2017_RS', 'Integration_SQL2019_RS', 'Integration_SQL2022_RS') {
It 'Should return file version information for any executable with Force parameter' {
# Get the install folder from the setup configuration
$setupConfig = Get-SqlDscRSSetupConfiguration -InstanceName 'SSRS' -ErrorAction 'Stop'

$executablePath = Join-Path -Path $setupConfig.InstallFolder -ChildPath 'RSHostingService/ReportingServicesService.exe'

# Using Force should work and return the file version info
$result = Get-SqlDscRSPackage -FilePath $executablePath -Force -ErrorAction 'Stop'

$result | Should -Not -BeNullOrEmpty
$result.FileVersion | Should -Not -BeNullOrEmpty
}
}

Context 'When using Force parameter to bypass validation' -Tag @('Integration_PowerBI') {
It 'Should return file version information for any executable with Force parameter' {
# Get the install folder from the setup configuration
$setupConfig = Get-SqlDscRSSetupConfiguration -InstanceName 'PBIRS' -ErrorAction 'Stop'

$executablePath = Join-Path -Path $setupConfig.InstallFolder -ChildPath 'RSHostingService/ReportingServicesService.exe'

# Using Force should work and return the file version info
$result = Get-SqlDscRSPackage -FilePath $executablePath -Force -ErrorAction 'Stop'

$result | Should -Not -BeNullOrEmpty
$result.FileVersion | Should -Not -BeNullOrEmpty
}
}
}
2 changes: 2 additions & 0 deletions tests/Integration/Commands/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ Save-SqlDscSqlServerMediaFile | 0 | - | - | Downloads SQL Server media files
Import-SqlDscPreferredModule | 0 | - | - | -
Install-SqlDscReportingService | 1 | 0 (Prerequisites) | - | SSRS instance
Get-SqlDscInstalledInstance | 2 | 1 (Install-SqlDscReportingService), 0 (Prerequisites) | SSRS | -
Get-SqlDscRSPackage | 2 | 1 (Install-SqlDscReportingService), 0 (Prerequisites) | SSRS | -
Get-SqlDscRSSetupConfiguration | 2 | 1 (Install-SqlDscReportingService), 0 (Prerequisites) | SSRS | -
Test-SqlDscRSInstalled | 2 | 1 (Install-SqlDscReportingService), 0 (Prerequisites) | SSRS | -
Repair-SqlDscReportingService | 8 | 1 (Install-SqlDscReportingService) | SSRS | -
Expand All @@ -180,6 +181,7 @@ Save-SqlDscSqlServerMediaFile | 0 | - | - | Downloads SQL Server media files
Import-SqlDscPreferredModule | 0 | - | - | -
Install-SqlDscPowerBIReportServer | 1 | 0 (Prerequisites) | - | PBIRS instance
Get-SqlDscInstalledInstance | 2 | 1 (Install-SqlDscPowerBIReportServer), 0 (Prerequisites) | PBIRS | -
Get-SqlDscRSPackage | 2 | 1 (Install-SqlDscPowerBIReportServer), 0 (Prerequisites) | PBIRS | -
Get-SqlDscRSSetupConfiguration | 2 | 1 (Install-SqlDscPowerBIReportServer), 0 (Prerequisites) | PBIRS | -
Test-SqlDscRSInstalled | 2 | 1 (Install-SqlDscPowerBIReportServer), 0 (Prerequisites) | PBIRS | -
Repair-SqlDscPowerBIReportServer | 8 | 1 (Install-SqlDscPowerBIReportServer) | PBIRS | -
Expand Down
22 changes: 21 additions & 1 deletion tests/QA/ScriptAnalyzer.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,27 @@ BeforeDiscovery {
(from Indented.ScriptAnalyzerRules) can properly parse parameters that uses SMO types,
e.g. [Microsoft.SqlServer.Management.Smo.Server].
#>
Add-Type -Path "$PSScriptRoot/../Unit/Stubs/SMO.cs" -ReferencedAssemblies 'System.Data', 'System.Xml'
if ($IsLinux -or $IsMacOS)
{
# .NET Core requires different assemblies than .NET Framework
$referencedAssemblies = @(
'System.Collections'
'System.Collections.Specialized'
'System.Data.Common'
'System.Linq'
'System.Net.Primitives'
'netstandard'
)
}
else
{
$referencedAssemblies = @(
'System.Data'
'System.Xml'
)
}

Add-Type -Path "$PSScriptRoot/../Unit/Stubs/SMO.cs" -ReferencedAssemblies $referencedAssemblies

$repositoryPath = Resolve-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '../..')
$sourcePath = Join-Path -Path $repositoryPath -ChildPath 'source'
Expand Down
Loading
Loading