diff --git a/CHANGELOG.md b/CHANGELOG.md index a07974526..fc05d85a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 b/DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 index 89f9feb32..77623cd7c 100644 --- a/DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 +++ b/DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 @@ -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) ) { @@ -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 @@ -905,6 +929,7 @@ function Get-ReportingServicesData @{ Configuration = $reportingServicesConfiguration ReportsApplicationName = $reportsApplicationName + SqlVersion = $sqlVersion } } @@ -946,7 +971,7 @@ function Invoke-RsCimMethod ErrorAction = 'Stop' } - if ($PSBoundParameters.ContainsKey('Arguments')) + if ( $PSBoundParameters.ContainsKey('Arguments') ) { $invokeCimMethodParameters['Arguments'] = $Arguments } @@ -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 diff --git a/Modules/DscResource.Common/DscResource.Common.psm1 b/Modules/DscResource.Common/DscResource.Common.psm1 index db818c733..4ed14410a 100644 --- a/Modules/DscResource.Common/DscResource.Common.psm1 +++ b/Modules/DscResource.Common/DscResource.Common.psm1 @@ -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. diff --git a/Tests/Integration/MSFT_SqlRS.Integration.Tests.ps1 b/Tests/Integration/MSFT_SqlRS.Integration.Tests.ps1 index 492fdb216..fa94d1ef8 100644 --- a/Tests/Integration/MSFT_SqlRS.Integration.Tests.ps1 +++ b/Tests/Integration/MSFT_SqlRS.Integration.Tests.ps1 @@ -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 } @@ -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 { @@ -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 { @@ -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 { @@ -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 } @@ -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 { diff --git a/Tests/Integration/MSFT_SqlRS.config.ps1 b/Tests/Integration/MSFT_SqlRS.config.ps1 index 702715389..0c2b1f45e 100644 --- a/Tests/Integration/MSFT_SqlRS.config.ps1 +++ b/Tests/Integration/MSFT_SqlRS.config.ps1 @@ -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 = @( @{ @@ -27,7 +40,7 @@ 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' @@ -35,7 +48,7 @@ else 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 @@ -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' + } } } } @@ -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' + } } } } diff --git a/Tests/Unit/DscResource.Common.Tests.ps1 b/Tests/Unit/DscResource.Common.Tests.ps1 index 6e175df60..7a9aeb079 100644 --- a/Tests/Unit/DscResource.Common.Tests.ps1 +++ b/Tests/Unit/DscResource.Common.Tests.ps1 @@ -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' diff --git a/Tests/Unit/MSFT_SqlRS.Tests.ps1 b/Tests/Unit/MSFT_SqlRS.Tests.ps1 index 5b3c8dc7f..067ad4db7 100644 --- a/Tests/Unit/MSFT_SqlRS.Tests.ps1 +++ b/Tests/Unit/MSFT_SqlRS.Tests.ps1 @@ -99,13 +99,6 @@ try } } - $mockGetItemProperty = { - return @{ - InstanceName = $mockInstanceName - Version = $mockDynamic_SqlBuildVersion - } - } - $mockGetCimInstance_ConfigurationSetting_NamedInstance = { return @( ( @@ -157,12 +150,9 @@ try Describe "SqlRS\Get-TargetResource" -Tag 'Get' { BeforeAll { - $mockDynamic_SqlBuildVersion = '13.0.4001.0' - - Mock -CommandName Get-ItemProperty -MockWith $mockGetItemProperty -Verifiable Mock -CommandName Invoke-RsCimMethod -MockWith $mockInvokeRsCimMethod_ListReservedUrls -ParameterFilter { $MethodName -eq 'ListReservedUrls' - } -Verifiable + } <# This is mocked here so that no calls are made to it directly, @@ -179,19 +169,20 @@ try Context 'When the system is in the desired state' { BeforeAll { + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = (& $mockGetCimInstance_ConfigurationSetting_NamedInstance)[0] + ReportsApplicationName = 'ReportServerWebApp' + SqlVersion = 13 + } + } + $mockDynamicReportServerApplicationName = $mockReportServerApplicationName $mockDynamicReportsApplicationName = $mockReportsApplicationName $mockDynamicReportsApplicationUrlString = $mockReportsApplicationUrl $mockDynamicReportServerApplicationUrlString = $mockReportServerApplicationUrl } - BeforeEach { - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_ConfigurationSetting_NamedInstance ` - -ParameterFilter $mockGetCimInstance_ConfigurationSetting_ParameterFilter ` - -Verifiable - } - $mockDynamicIsInitialized = $true It 'Should return the same values as passed as parameters' { $resultGetTargetResource = Get-TargetResource @defaultParameters @@ -239,10 +230,13 @@ try Context 'When the system is not in the desired state' { BeforeEach { - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_ConfigurationSetting_DefaultInstance ` - -ParameterFilter $mockGetCimInstance_ConfigurationSetting_ParameterFilter ` - -Verifiable + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = (& $mockGetCimInstance_ConfigurationSetting_DefaultInstance)[0] + ReportsApplicationName = 'ReportServerWebApp' + SqlVersion = 13 + } + } $testParameters = $defaultParameters.Clone() $testParameters['InstanceName'] = $mockDefaultInstanceName @@ -290,28 +284,29 @@ try $resultGetTargetResource.IsInitialized | Should -Be $false } } + } - Context 'When there is no Reporting Services instance' { - BeforeEach { - Mock -CommandName Get-ItemProperty + Context 'When there is no Reporting Services instance' { + BeforeAll { + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = $null + } } + } - It 'Should throw the correct error message' { - { Get-TargetResource @defaultParameters } | Should -Throw 'SQL Reporting Services instance ''INSTANCE'' does not exist!' - } + It 'Should throw the correct error message' { + { Get-TargetResource @defaultParameters } | Should -Throw 'SQL Reporting Services instance ''INSTANCE'' does not exist!' } } - - Assert-VerifiableMock } Describe "SqlRS\Set-TargetResource" -Tag 'Set' { BeforeAll { - Mock -CommandName Import-SQLPSModule -Verifiable - Mock -CommandName Invoke-Sqlcmd -Verifiable - Mock -CommandName Get-ItemProperty -MockWith $mockGetItemProperty -Verifiable - Mock -CommandName Restart-ReportingServicesService -Verifiable - Mock -CommandName Invoke-RsCimMethod -Verifiable + Mock -CommandName Import-SQLPSModule + Mock -CommandName Invoke-Sqlcmd + Mock -CommandName Restart-ReportingServicesService + Mock -CommandName Invoke-RsCimMethod Mock -CommandName Invoke-RsCimMethod -MockWith $mockInvokeRsCimMethod_GenerateDatabaseCreationScript -ParameterFilter { $MethodName -eq 'GenerateDatabaseCreationScript' } @@ -332,369 +327,386 @@ try $mockDynamicReportServerApplicationUrlString = $mockReportServerApplicationUrl } - Context 'When the system is not in the desired state' { - Context 'When configuring a named instance that are not initialized' { - BeforeAll { - $mockDynamic_SqlBuildVersion = '13.0.4001.0' - $mockDynamicIsInitialized = $false - - Mock -CommandName Test-TargetResource -MockWith { - return $true - } - $defaultParameters = @{ - InstanceName = $mockNamedInstanceName - DatabaseServerName = $mockReportingServicesDatabaseServerName - DatabaseInstanceName = $mockReportingServicesDatabaseNamedInstanceName - UseSsl = $true - } - } + $sqlVersions = @( + @{ + VersionName = "SQL Server Reporting Services 2016" + Version = 13 + } + @{ + VersionName = "SQL Server Reporting Services 2017" + Version = 14 + } + ) + foreach($sqlVersion in $sqlVersions) + { + Context "When the system is not in the desired state ($($sqlVersion.VersionName))" { + Context "When configuring a named instance that are not initialized ($($sqlVersion.VersionName))" { + BeforeAll { + $mockDynamicIsInitialized = $false + + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = (& $mockGetCimInstance_ConfigurationSetting_NamedInstance)[0] + ReportsApplicationName = 'ReportServerWebApp' + SqlVersion = $sqlVersion.Version + } + } - BeforeEach { - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_ConfigurationSetting_NamedInstance ` - -ParameterFilter $mockGetCimInstance_ConfigurationSetting_ParameterFilter ` - -Verifiable + Mock -CommandName Test-TargetResource -MockWith { + return $true + } - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_Language ` - -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter ` - -Verifiable - } + $defaultParameters = @{ + InstanceName = $mockNamedInstanceName + DatabaseServerName = $mockReportingServicesDatabaseServerName + DatabaseInstanceName = $mockReportingServicesDatabaseNamedInstanceName + UseSsl = $true + } + } - It 'Should configure Reporting Service without throwing an error' { - { Set-TargetResource @defaultParameters } | Should -Not -Throw + BeforeEach { + Mock -CommandName Get-CimInstance ` + -MockWith $mockGetCimInstance_Language ` + -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter + } - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetSecureConnectionLevel' - } -Exactly -Times 1 -Scope It + It 'Should configure Reporting Service without throwing an error' { + { Set-TargetResource @defaultParameters } | Should -Not -Throw - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'RemoveURL' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetSecureConnectionLevel' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'InitializeReportServer' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'RemoveURL' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetDatabaseConnection' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'InitializeReportServer' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'GenerateDatabaseRightsScript' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetDatabaseConnection' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'GenerateDatabaseCreationScript' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'GenerateDatabaseRightsScript' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'GenerateDatabaseCreationScript' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportsApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportsApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportsApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 3 -Scope It - Assert-MockCalled -CommandName Invoke-Sqlcmd -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Restart-ReportingServicesService -Exactly -Times 1 -Scope It - } + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportsApplicationName + } -Exactly -Times 1 -Scope It - Context 'When there is no Reporting Services instance after Set-TargetResource has been called' { - BeforeEach { - Mock -CommandName Get-ItemProperty -Verifiable - Mock -CommandName Test-TargetResource -Verifiable + Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-Sqlcmd -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Restart-ReportingServicesService -Exactly -Times 1 -Scope It } - It 'Should throw the correct error message' { + Context 'When there is no Reporting Services instance after Set-TargetResource has been called' { + BeforeEach { + Mock -CommandName Get-ItemProperty + Mock -CommandName Test-TargetResource + } + + It 'Should throw the correct error message' { { Set-TargetResource @defaultParameters } | Should -Throw $script:localizedData.TestFailedAfterSet + } } - } - Context 'When it is not possible to evaluate OSLanguage' { - BeforeEach { - Mock -CommandName Get-CimInstance -MockWith { - return $null - } -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter -Verifiable } + Context 'When it is not possible to evaluate OSLanguage' { + BeforeEach { + Mock -CommandName Get-CimInstance -MockWith { + return $null + } -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter } - It 'Should throw the correct error message' { - { Set-TargetResource @defaultParameters } | Should -Throw 'Unable to find WMI object Win32_OperatingSystem.' + It 'Should throw the correct error message' { + { Set-TargetResource @defaultParameters } | Should -Throw 'Unable to find WMI object Win32_OperatingSystem.' + } } } - } - Context 'When configuring a named instance that are already initialized' { - BeforeAll { - $mockDynamic_SqlBuildVersion = '13.0.4001.0' - $mockDynamicIsInitialized = $true + Context "When configuring a named instance that are already initialized ($($sqlVersion.VersionName))" { + BeforeAll { + $mockDynamicIsInitialized = $true - Mock -CommandName Get-TargetResource -MockWith { - return @{ - ReportServerReservedUrl = $mockReportServerApplicationUrl - ReportsReservedUrl = $mockReportsApplicationUrl + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = (& $mockGetCimInstance_ConfigurationSetting_NamedInstance)[0] + ReportsApplicationName = 'ReportServerWebApp' + SqlVersion = $sqlVersion.Version + } } - } - Mock -CommandName Test-TargetResource -MockWith { - return $true + Mock -CommandName Get-TargetResource -MockWith { + return @{ + ReportServerReservedUrl = $mockReportServerApplicationUrl + ReportsReservedUrl = $mockReportsApplicationUrl + } + } + + Mock -CommandName Test-TargetResource -MockWith { + return $true + } + + $testParameters = @{ + InstanceName = $mockNamedInstanceName + DatabaseServerName = $mockReportingServicesDatabaseServerName + DatabaseInstanceName = $mockReportingServicesDatabaseNamedInstanceName + ReportServerVirtualDirectory = 'ReportServer_NewName' + ReportsVirtualDirectory = 'Reports_NewName' + ReportServerReservedUrl = 'https://+:4443' + ReportsReservedUrl = 'https://+:4443' + UseSsl = $true + } } - $testParameters = @{ - InstanceName = $mockNamedInstanceName - DatabaseServerName = $mockReportingServicesDatabaseServerName - DatabaseInstanceName = $mockReportingServicesDatabaseNamedInstanceName - ReportServerVirtualDirectory = 'ReportServer_NewName' - ReportsVirtualDirectory = 'Reports_NewName' - ReportServerReservedUrl = 'https://+:4443' - ReportsReservedUrl = 'https://+:4443' - UseSsl = $true + BeforeEach { + Mock -CommandName Get-CimInstance ` + -MockWith $mockGetCimInstance_Language ` + -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter } - } - BeforeEach { - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_ConfigurationSetting_NamedInstance ` - -ParameterFilter $mockGetCimInstance_ConfigurationSetting_ParameterFilter ` - -Verifiable + It 'Should configure Reporting Service without throwing an error' { + { Set-TargetResource @testParameters } | Should -Not -Throw - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_Language ` - -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter ` - -Verifiable - } + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetSecureConnectionLevel' + } -Exactly -Times 1 -Scope It - It 'Should configure Reporting Service without throwing an error' { - { Set-TargetResource @testParameters } | Should -Not -Throw + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'RemoveURL' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetSecureConnectionLevel' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'RemoveURL' -and $Arguments.Application -eq $mockReportsApplicationName + } -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'RemoveURL' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'InitializeReportServer' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'RemoveURL' -and $Arguments.Application -eq $mockReportsApplicationName - } -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetDatabaseConnection' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'InitializeReportServer' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'GenerateDatabaseRightsScript' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetDatabaseConnection' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'GenerateDatabaseCreationScript' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'GenerateDatabaseRightsScript' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'GenerateDatabaseCreationScript' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportsApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportsApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportsApplicationName + } -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-Sqlcmd -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Restart-ReportingServicesService -Exactly -Times 1 -Scope It + } + } - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportsApplicationName - } -Exactly -Times 2 -Scope It + Context "When configuring a named instance that are already initialized ($($sqlVersion.VersionName)), suppress restart" { + BeforeAll { + $mockDynamicIsInitialized = $true - Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-Sqlcmd -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Restart-ReportingServicesService -Exactly -Times 1 -Scope It - } - } + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = (& $mockGetCimInstance_ConfigurationSetting_NamedInstance)[0] + ReportsApplicationName = 'ReportServerWebApp' + SqlVersion = $sqlVersion.Version + } + } - Context 'When configuring a named instance that are already initialized, suppress restart' { - BeforeAll { - $mockDynamic_SqlBuildVersion = '13.0.4001.0' - $mockDynamicIsInitialized = $true + Mock -CommandName Get-TargetResource -MockWith { + return @{ + ReportServerReservedUrl = $mockReportServerApplicationUrl + ReportsReservedUrl = $mockReportsApplicationUrl + } + } - Mock -CommandName Get-TargetResource -MockWith { - return @{ - ReportServerReservedUrl = $mockReportServerApplicationUrl - ReportsReservedUrl = $mockReportsApplicationUrl + Mock -CommandName Test-TargetResource -MockWith { + return $true } - } - Mock -CommandName Test-TargetResource -MockWith { - return $true + $testParameters = @{ + InstanceName = $mockNamedInstanceName + DatabaseServerName = $mockReportingServicesDatabaseServerName + DatabaseInstanceName = $mockReportingServicesDatabaseNamedInstanceName + ReportServerVirtualDirectory = 'ReportServer_NewName' + ReportsVirtualDirectory = 'Reports_NewName' + ReportServerReservedUrl = 'https://+:4443' + ReportsReservedUrl = 'https://+:4443' + UseSsl = $true + SuppressRestart = $true + } } - $testParameters = @{ - InstanceName = $mockNamedInstanceName - DatabaseServerName = $mockReportingServicesDatabaseServerName - DatabaseInstanceName = $mockReportingServicesDatabaseNamedInstanceName - ReportServerVirtualDirectory = 'ReportServer_NewName' - ReportsVirtualDirectory = 'Reports_NewName' - ReportServerReservedUrl = 'https://+:4443' - ReportsReservedUrl = 'https://+:4443' - UseSsl = $true - SuppressRestart = $true + BeforeEach { + Mock -CommandName Get-CimInstance ` + -MockWith $mockGetCimInstance_Language ` + -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter } - } - - BeforeEach { - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_ConfigurationSetting_NamedInstance ` - -ParameterFilter $mockGetCimInstance_ConfigurationSetting_ParameterFilter ` - -Verifiable - - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_Language ` - -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter ` - -Verifiable - } - It 'Should configure Reporting Service without throwing an error' { - { Set-TargetResource @testParameters } | Should -Not -Throw + It 'Should configure Reporting Service without throwing an error' { + { Set-TargetResource @testParameters } | Should -Not -Throw - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetSecureConnectionLevel' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetSecureConnectionLevel' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'RemoveURL' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'RemoveURL' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'RemoveURL' -and $Arguments.Application -eq $mockReportsApplicationName - } -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'RemoveURL' -and $Arguments.Application -eq $mockReportsApplicationName + } -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'InitializeReportServer' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'InitializeReportServer' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetDatabaseConnection' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetDatabaseConnection' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'GenerateDatabaseRightsScript' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'GenerateDatabaseRightsScript' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'GenerateDatabaseCreationScript' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'GenerateDatabaseCreationScript' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportsApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportsApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportsApplicationName - } -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportsApplicationName + } -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Invoke-Sqlcmd -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Restart-ReportingServicesService -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-Sqlcmd -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Restart-ReportingServicesService -Exactly -Times 0 -Scope It + } } - } - Context 'When configuring a default instance that are not initialized' { - BeforeAll { - $mockDynamic_SqlBuildVersion = '12.0.4100.1' - $mockDynamicIsInitialized = $false + Context "When configuring a default instance that are not initialized ($($sqlVersion.VersionName))" { + BeforeAll { + $mockDynamicIsInitialized = $false - Mock -CommandName Test-TargetResource -MockWith { - return $true - } -Verifiable + Mock -CommandName Test-TargetResource -MockWith { + return $true + } - $defaultParameters = @{ - InstanceName = $mockDefaultInstanceName - DatabaseServerName = $mockReportingServicesDatabaseServerName - DatabaseInstanceName = $mockReportingServicesDatabaseDefaultInstanceName + $defaultParameters = @{ + InstanceName = $mockDefaultInstanceName + DatabaseServerName = $mockReportingServicesDatabaseServerName + DatabaseInstanceName = $mockReportingServicesDatabaseDefaultInstanceName + } } - } - BeforeEach { - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_ConfigurationSetting_DefaultInstance ` - -ParameterFilter $mockGetCimInstance_ConfigurationSetting_ParameterFilter ` - -Verifiable + BeforeEach { + # This mocks the SQL Server Reporting Services 2014 and older + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = (& $mockGetCimInstance_ConfigurationSetting_DefaultInstance)[0] + ReportsApplicationName = 'ReportManager' + SqlVersion = $sqlVersion.Version + } + } - Mock -CommandName Get-CimInstance ` - -MockWith $mockGetCimInstance_Language ` - -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter ` - -Verifiable - } + Mock -CommandName Get-CimInstance ` + -MockWith $mockGetCimInstance_Language ` + -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter + } - It 'Should configure Reporting Service without throwing an error' { - { Set-TargetResource @defaultParameters } | Should -Not -Throw + It 'Should configure Reporting Service without throwing an error' { + { Set-TargetResource @defaultParameters } | Should -Not -Throw - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'RemoveURL' - } -Exactly -Times 0 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'RemoveURL' + } -Exactly -Times 0 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'InitializeReportServer' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'InitializeReportServer' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetDatabaseConnection' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetDatabaseConnection' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'GenerateDatabaseRightsScript' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'GenerateDatabaseRightsScript' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'GenerateDatabaseCreationScript' - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'GenerateDatabaseCreationScript' + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportsApplicationNameLegacy - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'SetVirtualDirectory' -and $Arguments.Application -eq $mockReportsApplicationNameLegacy + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportServerApplicationName - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportServerApplicationName + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { - $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportsApplicationNameLegacy - } -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-RsCimMethod -ParameterFilter { + $MethodName -eq 'ReserveUrl' -and $Arguments.Application -eq $mockReportsApplicationNameLegacy + } -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 3 -Scope It - Assert-MockCalled -CommandName Invoke-Sqlcmd -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Restart-ReportingServicesService -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-Sqlcmd -Exactly -Times 2 -Scope It + Assert-MockCalled -CommandName Restart-ReportingServicesService -Exactly -Times 1 -Scope It + } } } } - - Assert-VerifiableMock } Describe "SqlRS\Test-TargetResource" -Tag 'Test' { @@ -705,7 +717,7 @@ try return @{ IsInitialized = $false } - } -Verifiable + } $testParameters = @{ InstanceName = $mockNamedInstanceName @@ -728,7 +740,7 @@ try ReportServerVirtualDirectory = $mockVirtualDirectoryReportServerName ReportsVirtualDirectory = $mockVirtualDirectoryReportsName } - } -Verifiable + } $testParameters = @{ InstanceName = $mockNamedInstanceName @@ -753,7 +765,7 @@ try ReportServerVirtualDirectory = $mockVirtualDirectoryReportServerName ReportsVirtualDirectory = $mockVirtualDirectoryReportsName } - } -Verifiable + } $testParameters = @{ InstanceName = $mockNamedInstanceName @@ -777,7 +789,7 @@ try IsInitialized = $true ReportServerReservedUrl = $mockReportServerApplicationUrl } - } -Verifiable + } $testParameters = @{ InstanceName = $mockNamedInstanceName @@ -800,7 +812,7 @@ try IsInitialized = $true ReportsReservedUrl = $mockReportServerApplicationUrl } - } -Verifiable + } $testParameters = @{ InstanceName = $mockNamedInstanceName @@ -825,7 +837,7 @@ try IsInitialized = $true UseSsl = $false } - } -Verifiable + } $testParameters = @{ InstanceName = $mockNamedInstanceName @@ -848,7 +860,7 @@ try return @{ IsInitialized = $true } - } -Verifiable + } $defaultParameters = @{ InstanceName = $mockNamedInstanceName @@ -862,8 +874,6 @@ try $resultTestTargetResource | Should -Be $true } } - - Assert-VerifiableMock } Describe "SqlRS\Invoke-RsCimMethod" -Tag 'Helper' { @@ -880,7 +890,7 @@ try return @{ HRESULT = 0 } - } -Verifiable + } } Context 'When calling Invoke-CimMethod without arguments' { @@ -927,7 +937,7 @@ try HRESULT = 1 Error = 'Something went wrong' } - } -Verifiable + } } It 'Should call Invoke-CimMethod and throw the correct error' { @@ -950,7 +960,7 @@ try return New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'HRESULT' -Value 1 -PassThru | Add-Member -MemberType NoteProperty -Name 'ExtendedErrors' -Value @('Something went wrong', 'Another thing went wrong') -PassThru -Force - } -Verifiable + } } It 'Should call Invoke-CimMethod and throw the correct error' { @@ -967,8 +977,170 @@ try } } } + } + + Describe 'SqlRS\Get-ReportingServicesData' -Tag 'Helper' { + BeforeAll { + $mockInstanceId = 'MSRS13.{0}' -f $mockNamedInstanceName + $mockGetItemProperty_InstanceNames = { + return @{ + $mockNamedInstanceName = $mockInstanceId + } + } + + $mockGetItemProperty_InstanceNames_ParameterFilter = { + $Path -eq 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS' + } + + $mockSql2014Version = '12.0.6024.0' + $mockGetItemProperty_Sql2014 = { + return @{ + Version = $mockSql2014Version + } + } + + $mockSql2016Version = '13.0.4001.0' + $mockGetItemProperty_Sql2016 = { + return @{ + Version = $mockSql2016Version + } + } + + $mockSql2017Version = '14.0.6514.11481' + $mockGetItemProperty_Sql2017 = { + return @{ + CurrentVersion = $mockSql2017Version + } + } + + $mockGetItemProperty_Sql2014AndSql2016_ParameterFilter = { + $Path -eq ('HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\Setup' -f $mockInstanceId) + } + + $mockGetItemProperty_Sql2017_ParameterFilter = { + $Path -eq ('HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\MSSQLServer\CurrentVersion' -f $mockInstanceId) + } + + $mockDynamicIsInitialized = $false + $mockDynamicSecureConnectionLevel = 0 + } + + Context 'When there is a Reporting Services instance' { + BeforeEach { + Mock -CommandName Get-ItemProperty ` + -MockWith $mockGetItemProperty_InstanceNames ` + -ParameterFilter $mockGetItemProperty_InstanceNames_ParameterFilter + + Mock -CommandName Get-CimInstance ` + -MockWith $mockGetCimInstance_ConfigurationSetting_NamedInstance ` + -ParameterFilter $mockGetCimInstance_ConfigurationSetting_ParameterFilter ` + } - Assert-VerifiableMock + Context 'When the instance is SQL Server Reporting Services 2014 or older' { + BeforeEach { + Mock -CommandName Test-Path -MockWith { + return $false + } + + Mock -CommandName Get-ItemProperty ` + -MockWith $mockGetItemProperty_Sql2014 ` + -ParameterFilter $mockGetItemProperty_Sql2014AndSql2016_ParameterFilter + } + + It 'Should return the correct information' { + $getReportingServicesDataResult = Get-ReportingServicesData -InstanceName $mockNamedInstanceName + $getReportingServicesDataResult.Configuration | Should -BeOfType [Microsoft.Management.Infrastructure.CimInstance] + $getReportingServicesDataResult.Configuration.InstanceName | Should -Be $mockNamedInstanceName + $getReportingServicesDataResult.Configuration.DatabaseServerName | Should -Be "$mockReportingServicesDatabaseServerName\$mockReportingServicesDatabaseNamedInstanceName" + $getReportingServicesDataResult.Configuration.IsInitialized | Should -Be $false + $getReportingServicesDataResult.Configuration.VirtualDirectoryReportServer | Should -Be $mockVirtualDirectoryReportServerName + $getReportingServicesDataResult.Configuration.VirtualDirectoryReportManager | Should -Be $mockVirtualDirectoryReportManagerName + $getReportingServicesDataResult.Configuration.SecureConnectionLevel | Should -Be 0 + $getReportingServicesDataResult.ReportsApplicationName | Should -Be 'ReportManager' + $getReportingServicesDataResult.SqlVersion | Should -Be $mockSql2014Version.Split('.')[0] + + Assert-MockCalled -CommandName Get-ItemProperty ` + -ParameterFilter $mockGetItemProperty_InstanceNames_ParameterFilter ` + -Exactly -Times 2 -Scope 'It' + + Assert-MockCalled -CommandName Get-ItemProperty ` + -ParameterFilter $mockGetItemProperty_Sql2014AndSql2016_ParameterFilter ` + -Exactly -Times 1 -Scope 'It' + + Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 1 -Scope 'It' + } + } + + Context 'When the instance is SQL Server Reporting Services 2016' { + BeforeEach { + Mock -CommandName Test-Path -MockWith { + return $false + } + + Mock -CommandName Get-ItemProperty ` + -MockWith $mockGetItemProperty_Sql2016 ` + -ParameterFilter $mockGetItemProperty_Sql2014AndSql2016_ParameterFilter + } + + It 'Should return the correct information' { + $getReportingServicesDataResult = Get-ReportingServicesData -InstanceName $mockNamedInstanceName + $getReportingServicesDataResult.Configuration | Should -BeOfType [Microsoft.Management.Infrastructure.CimInstance] + $getReportingServicesDataResult.Configuration.InstanceName | Should -Be $mockNamedInstanceName + $getReportingServicesDataResult.Configuration.DatabaseServerName | Should -Be "$mockReportingServicesDatabaseServerName\$mockReportingServicesDatabaseNamedInstanceName" + $getReportingServicesDataResult.Configuration.IsInitialized | Should -Be $false + $getReportingServicesDataResult.Configuration.VirtualDirectoryReportServer | Should -Be $mockVirtualDirectoryReportServerName + $getReportingServicesDataResult.Configuration.VirtualDirectoryReportManager | Should -Be $mockVirtualDirectoryReportManagerName + $getReportingServicesDataResult.Configuration.SecureConnectionLevel | Should -Be 0 + $getReportingServicesDataResult.ReportsApplicationName | Should -Be 'ReportServerWebApp' + $getReportingServicesDataResult.SqlVersion | Should -Be $mockSql2016Version.Split('.')[0] + + Assert-MockCalled -CommandName Get-ItemProperty ` + -ParameterFilter $mockGetItemProperty_InstanceNames_ParameterFilter ` + -Exactly -Times 2 -Scope 'It' + + Assert-MockCalled -CommandName Get-ItemProperty ` + -ParameterFilter $mockGetItemProperty_Sql2014AndSql2016_ParameterFilter ` + -Exactly -Times 1 -Scope 'It' + + Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 1 -Scope 'It' + } + } + + Context 'When the instance is SQL Server Reporting Services 2017' { + BeforeEach { + Mock -CommandName Test-Path -MockWith { + return $true + } + + Mock -CommandName Get-ItemProperty ` + -MockWith $mockGetItemProperty_Sql2017 ` + -ParameterFilter $mockGetItemProperty_Sql2017_ParameterFilter + } + + It 'Should return the correct information' { + $getReportingServicesDataResult = Get-ReportingServicesData -InstanceName $mockNamedInstanceName + $getReportingServicesDataResult.Configuration | Should -BeOfType [Microsoft.Management.Infrastructure.CimInstance] + $getReportingServicesDataResult.Configuration.InstanceName | Should -Be $mockNamedInstanceName + $getReportingServicesDataResult.Configuration.DatabaseServerName | Should -Be "$mockReportingServicesDatabaseServerName\$mockReportingServicesDatabaseNamedInstanceName" + $getReportingServicesDataResult.Configuration.IsInitialized | Should -Be $false + $getReportingServicesDataResult.Configuration.VirtualDirectoryReportServer | Should -Be $mockVirtualDirectoryReportServerName + $getReportingServicesDataResult.Configuration.VirtualDirectoryReportManager | Should -Be $mockVirtualDirectoryReportManagerName + $getReportingServicesDataResult.Configuration.SecureConnectionLevel | Should -Be 0 + $getReportingServicesDataResult.ReportsApplicationName | Should -Be 'ReportServerWebApp' + $getReportingServicesDataResult.SqlVersion | Should -Be $mockSql2017Version.Split('.')[0] + + Assert-MockCalled -CommandName Get-ItemProperty ` + -ParameterFilter $mockGetItemProperty_InstanceNames_ParameterFilter ` + -Exactly -Times 2 -Scope 'It' + + Assert-MockCalled -CommandName Get-ItemProperty ` + -ParameterFilter $mockGetItemProperty_Sql2017_ParameterFilter ` + -Exactly -Times 1 -Scope 'It' + + Assert-MockCalled -CommandName Get-CimInstance -Exactly -Times 1 -Scope 'It' + } + } + } } } }