Skip to content

Commit

Permalink
SqlRs: [#864] SSRS 2017 username, service instance names (#1261)
Browse files Browse the repository at this point in the history
- Changes to SqlRS
  - Can now initialise SSRS 2017 instances (issue #864)
  • Loading branch information
bozho authored and johlju committed May 13, 2019
1 parent aee4542 commit 32927e8
Show file tree
Hide file tree
Showing 7 changed files with 694 additions and 368 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
When initializing Reporting Services, there is no need to execute `InitializeReportServer`
CIM method, since executing `SetDatabaseConnection` CIM method initializes
Reporting Services.
- [issue #864](https://github.com/PowerShell/SqlServerDsc/issues/864) SqlRs
can now initialise SSRS 2017 instances
- Changes to SqlServerLogin
- Added en-US localization ([issue #615](https://github.com/PowerShell/SqlServerDsc/issues/615)).
- Added unit tests to improved code coverage.
Expand Down
35 changes: 30 additions & 5 deletions DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,23 @@ function Set-TargetResource

if ( $null -ne $reportingServicesData.Configuration )
{
if ( $InstanceName -eq 'MSSQLSERVER' )
if ( $reportingServicesData.SqlVersion -ge 14 )
{
if ( [string]::IsNullOrEmpty($ReportServerVirtualDirectory) )
{
$ReportServerVirtualDirectory = 'ReportServer'
}

if ( [string]::IsNullOrEmpty($ReportsVirtualDirectory) )
{
$ReportsVirtualDirectory = 'Reports'
}

$reportingServicesServiceName = 'SQLServerReportingServices'
$reportingServicesDatabaseName = 'ReportServer'

}
elseif ( $InstanceName -eq 'MSSQLSERVER' )
{
if ( [System.String]::IsNullOrEmpty($ReportServerVirtualDirectory) )
{
Expand Down Expand Up @@ -882,7 +898,15 @@ function Get-ReportingServicesData
if ( Get-ItemProperty -Path $instanceNamesRegistryKey -Name $InstanceName -ErrorAction SilentlyContinue )
{
$instanceId = (Get-ItemProperty -Path $instanceNamesRegistryKey -Name $InstanceName).$InstanceName
$sqlVersion = [System.Int32]((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instanceId\Setup" -Name 'Version').Version).Split('.')[0]

if( Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instanceId\MSSQLServer\CurrentVersion" )
{
# SQL Server 2017 SSRS stores current SQL Server version to a different Registry path.
$sqlVersion = [int]((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceId\MSSQLServer\CurrentVersion" -Name "CurrentVersion").CurrentVersion).Split(".")[0]
}
else {
$sqlVersion = [int]((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instanceId\Setup" -Name "Version").Version).Split(".")[0]
}
$reportingServicesConfiguration = Get-CimInstance -ClassName MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$sqlVersion\Admin"
$reportingServicesConfiguration = $reportingServicesConfiguration | Where-Object -FilterScript {
$_.InstanceName -eq $InstanceName
Expand All @@ -905,6 +929,7 @@ function Get-ReportingServicesData
@{
Configuration = $reportingServicesConfiguration
ReportsApplicationName = $reportsApplicationName
SqlVersion = $sqlVersion
}
}

Expand Down Expand Up @@ -946,7 +971,7 @@ function Invoke-RsCimMethod
ErrorAction = 'Stop'
}

if ($PSBoundParameters.ContainsKey('Arguments'))
if ( $PSBoundParameters.ContainsKey('Arguments') )
{
$invokeCimMethodParameters['Arguments'] = $Arguments
}
Expand All @@ -957,9 +982,9 @@ function Invoke-RsCimMethod
If an general error occur in the Invoke-CimMethod, like calling a method
that does not exist, returns $null in $invokeCimMethodResult.
#>
if ($invokeCimMethodResult -and $invokeCimMethodResult.HRESULT -ne 0)
if ( $invokeCimMethodResult -and $invokeCimMethodResult.HRESULT -ne 0 )
{
if ($invokeCimMethodResult | Get-Member -Name 'ExtendedErrors')
if ( $invokeCimMethodResult | Get-Member -Name 'ExtendedErrors' )
{
<#
The returned object property ExtendedErrors is an array
Expand Down
28 changes: 22 additions & 6 deletions Modules/DscResource.Common/DscResource.Common.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -1336,15 +1336,31 @@ function Restart-ReportingServicesService
$WaitTime = 0
)

$ServiceName = 'ReportServer'

if (-not ($SQLInstanceName -eq 'MSSQLSERVER'))
if ($SQLInstanceName -eq 'SSRS')
{
$ServiceName += '${0}' -f $SQLInstanceName
# Check if we're dealing with SSRS 2017
$ServiceName = 'SQLServerReportingServices'

Write-Verbose -Message ($script:localizedData.GetServiceInformation -f $ServiceName) -Verbose
$reportingServicesService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
}

Write-Verbose -Message ($script:localizedData.GetServiceInformation -f 'Reporting Services') -Verbose
$reportingServicesService = Get-Service -Name $ServiceName
if ($null -eq $reportingServicesService)
{
$ServiceName = 'ReportServer'

<#
Pre-2017 SSRS support multiple instances, check if we're dealing
with a named instance.
#>
if (-not ($SQLInstanceName -eq 'MSSQLSERVER'))
{
$ServiceName += '${0}' -f $SQLInstanceName
}

Write-Verbose -Message ($script:localizedData.GetServiceInformation -f $ServiceName) -Verbose
$reportingServicesService = Get-Service -Name $ServiceName
}

<#
Get all dependent services that are running.
Expand Down
58 changes: 53 additions & 5 deletions Tests/Integration/MSFT_SqlRS.Integration.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ param()

Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\TestHelpers\CommonTestHelper.psm1')

if (Test-SkipContinuousIntegrationTask -Type 'Integration' -Category 'Integration_SQL2016')
if (Test-SkipContinuousIntegrationTask -Type 'Integration' -Category @('Integration_SQL2016','Integration_SQL2017'))
{
return
}
Expand All @@ -29,6 +29,22 @@ $TestEnvironment = Initialize-TestEnvironment `
-TestType Integration
#endregion

<#
This is used in both the configuration file and in this script file
to run the correct tests depending of what version of SQL Server is
being tested in the current job.
#>
if (Test-ContinuousIntegrationTaskCategory -Category 'Integration_SQL2017')
{
$script:sqlVersion = '140'
}
else
{
$script:sqlVersion = '130'
}

Write-Verbose -Message ('Running integration tests for SSRS version {0}' -f $script:sqlVersion) -Verbose

# Using try/finally to always cleanup.
try
{
Expand Down Expand Up @@ -117,7 +133,15 @@ try
}

It 'Should be able to access the ReportServer site without any error' {
$reportServerUri = 'http://{0}/ReportServer_{1}' -f $env:COMPUTERNAME, $ConfigurationData.AllNodes.InstanceName
if($script:sqlVersion -eq '140')
{
# SSRS 2017 does not support multiple instances
$reportServerUri = 'http://{0}/ReportServer' -f $env:COMPUTERNAME
}
else
{
$reportServerUri = 'http://{0}/ReportServer_{1}' -f $env:COMPUTERNAME, $ConfigurationData.AllNodes.InstanceName
}

try
{
Expand All @@ -139,7 +163,15 @@ try
}

It 'Should be able to access the Reports site without any error' {
$reportsUri = 'http://{0}/Reports_{1}' -f $env:COMPUTERNAME, $ConfigurationData.AllNodes.InstanceName
if($script:sqlVersion -eq '140')
{
# SSRS 2017 does not support multiple instances
$reportsUri = 'http://{0}/Reports' -f $env:COMPUTERNAME
}
else
{
$reportsUri = 'http://{0}/Reports_{1}' -f $env:COMPUTERNAME, $ConfigurationData.AllNodes.InstanceName
}

try
{
Expand Down Expand Up @@ -213,7 +245,15 @@ try
as this without testing for the correct error message on purpose.
#>
It 'Should not be able to access the ReportServer site and throw an error message' {
$reportServerUri = 'http://{0}/ReportServer_{1}' -f $env:COMPUTERNAME, $ConfigurationData.AllNodes.InstanceName
if($script:sqlVersion -eq '140')
{
# SSRS 2017 does not support multiple instances
$reportServerUri = 'http://{0}/ReportServer' -f $env:COMPUTERNAME
}
else
{
$reportServerUri = 'http://{0}/ReportServer_{1}' -f $env:COMPUTERNAME, $ConfigurationData.AllNodes.InstanceName
}

{ Invoke-WebRequest -Uri $reportServerUri -UseDefaultCredentials } | Should -Throw
}
Expand Down Expand Up @@ -265,7 +305,15 @@ try
}

It 'Should be able to access the ReportServer site without any error' {
$reportServerUri = 'http://{0}/ReportServer_{1}' -f $env:COMPUTERNAME, $ConfigurationData.AllNodes.InstanceName
if($script:sqlVersion -eq '140')
{
# SSRS 2017 does not support multiple instances
$reportServerUri = 'http://{0}/ReportServer' -f $env:COMPUTERNAME
}
else
{
$reportServerUri = 'http://{0}/ReportServer_{1}' -f $env:COMPUTERNAME, $ConfigurationData.AllNodes.InstanceName
}

try
{
Expand Down
94 changes: 66 additions & 28 deletions Tests/Integration/MSFT_SqlRS.config.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ else
$mockLastDrive = ((Get-Volume).DriveLetter | Sort-Object | Select-Object -Last 1)
$mockIsoMediaDriveLetter = [char](([int][char]$mockLastDrive) + 1)

if($script:sqlVersion -eq '140')
{
# SQL2017
$instanceName = 'SSRS'
$isoImageName = 'SQL2017.iso'
}
else
{
# SQL2016
$instanceName = 'DSCRS2016'
$isoImageName = 'SQL2016.iso'
}

$ConfigurationData = @{
AllNodes = @(
@{
Expand All @@ -27,15 +40,15 @@ else
Service_UserName = "$env:COMPUTERNAME\svc-Reporting"
Service_Password = 'yig-C^Equ3'

InstanceName = 'DSCRS2016'
InstanceName = $instanceName
Features = 'RS'
InstallSharedDir = 'C:\Program Files\Microsoft SQL Server'
InstallSharedWOWDir = 'C:\Program Files (x86)\Microsoft SQL Server'
UpdateEnabled = 'False'
SuppressReboot = $true # Make sure we don't reboot during testing.
ForceReboot = $false

ImagePath = "$env:TEMP\SQL2016.iso"
ImagePath = "$env:TEMP\$isoImageName"
DriveLetter = $mockIsoMediaDriveLetter

DatabaseServerName = $env:COMPUTERNAME
Expand Down Expand Up @@ -90,32 +103,46 @@ Configuration MSFT_SqlRS_CreateDependencies_Config
Ensure = 'Present'
}

SqlSetup 'InstallReportingServicesInstance'
if($script:sqlVersion -eq '130')
{
InstanceName = $Node.InstanceName
Features = $Node.Features
SourcePath = "$($Node.DriveLetter):\"
BrowserSvcStartupType = 'Automatic'
InstallSharedDir = $Node.InstallSharedDir
InstallSharedWOWDir = $Node.InstallSharedWOWDir
UpdateEnabled = $Node.UpdateEnabled
SuppressReboot = $Node.SuppressReboot
ForceReboot = $Node.ForceReboot
RSSvcAccount = New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList @($Node.Service_UserName, (ConvertTo-SecureString -String $Node.Service_Password -AsPlainText -Force))

DependsOn = @(
'[WaitForVolume]WaitForMountOfIsoMedia'
'[User]CreateReportingServicesServiceAccount'
'[WindowsFeature]NetFramework45'
)
SqlSetup 'InstallReportingServicesInstance'
{
InstanceName = $Node.InstanceName
Features = $Node.Features
SourcePath = "$($Node.DriveLetter):\"
BrowserSvcStartupType = 'Automatic'
InstallSharedDir = $Node.InstallSharedDir
InstallSharedWOWDir = $Node.InstallSharedWOWDir
UpdateEnabled = $Node.UpdateEnabled
SuppressReboot = $Node.SuppressReboot
ForceReboot = $Node.ForceReboot
RSSvcAccount = New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList @($Node.Service_UserName, (ConvertTo-SecureString -String $Node.Service_Password -AsPlainText -Force))

PsDscRunAsCredential = New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList @(
$Node.RunAs_UserName, (ConvertTo-SecureString -String $Node.RunAs_Password -AsPlainText -Force))
DependsOn = @(
'[WaitForVolume]WaitForMountOfIsoMedia'
'[User]CreateReportingServicesServiceAccount'
'[WindowsFeature]NetFramework45'
)

PsDscRunAsCredential = New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList @(
$Node.RunAs_UserName, (ConvertTo-SecureString -String $Node.RunAs_Password -AsPlainText -Force))
}
}
<#
MSFT_SqlRSSetup.Integration.Tests.ps1 will have installed SSRS 2017.
We just need to start SSRS.
#>
elseif($script:sqlVersion -eq '140')
{
Service 'StartReportingServicesInstance'
{
Name = 'SQLServerReportingServices'
State = 'Running'
}
}
}
}
Expand Down Expand Up @@ -222,10 +249,21 @@ Configuration MSFT_SqlRS_StopReportingServicesInstance_Config

node $AllNodes.NodeName
{
Service ('StopReportingServicesInstance{0}' -f $Node.InstanceName)
if($script:sqlVersion -eq '130')
{
Name = ('ReportServer${0}' -f $Node.InstanceName)
State = 'Stopped'
Service ('StopReportingServicesInstance{0}' -f $Node.InstanceName)
{
Name = ('ReportServer${0}' -f $Node.InstanceName)
State = 'Stopped'
}
}
elseif($script:sqlVersion -eq '140')
{
Service 'StopReportingServicesInstance'
{
Name = 'SQLServerReportingServices'
State = 'Stopped'
}
}
}
}
25 changes: 25 additions & 0 deletions Tests/Unit/DscResource.Common.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2634,6 +2634,31 @@ InModuleScope 'DscResource.Common' {
}
}

Context 'When restarting an SQL Server 2017 Report Services' {
BeforeAll {
$mockServiceName = 'SQLServerReportingServices'
$mockDependedServiceName = 'DependentService'

$mockDynamicServiceName = $mockServiceName
$mockDynamicDependedServiceName = $mockDependedServiceName
$mockDynamicServiceDisplayName = 'Reporting Services'

Mock -CommandName Stop-Service -Verifiable
Mock -CommandName Start-Service -Verifiable
Mock -CommandName Get-Service -MockWith $mockGetService
}

It 'Should restart the service and dependent service' {
{ Restart-ReportingServicesService -SQLInstanceName 'SSRS' } | Should -Not -Throw

Assert-MockCalled -CommandName Get-Service -ParameterFilter {
$Name -eq $mockServiceName
} -Scope It -Exactly -Times 1
Assert-MockCalled -CommandName Stop-Service -Scope It -Exactly -Times 1
Assert-MockCalled -CommandName Start-Service -Scope It -Exactly -Times 2
}
}

Context 'When restarting a Report Services named instance' {
BeforeAll {
$mockServiceName = 'ReportServer$TEST'
Expand Down
Loading

0 comments on commit 32927e8

Please sign in to comment.