diff --git a/CHANGELOG.md b/CHANGELOG.md index a451367369..67faab06b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -127,6 +127,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `SqlRS` - Obtain the Reporting service name from WMI for version 14 and higher. [issue #2313](https://github.com/dsccommunity/SqlServerDsc/issues/2313) + - Added validation to ensure Configuration.ServiceName is not null or empty + for SQL Server version 14 and higher [issue #2342](https://github.com/dsccommunity/SqlServerDsc/issues/2342). - `Repair-SqlDscServer` - Removed the `Features` parameter from the command as SQL Server Repair action does not accept the `/FEATURES` parameter. SQL Server automatically repairs diff --git a/source/DSCResources/DSC_SqlRS/DSC_SqlRS.psm1 b/source/DSCResources/DSC_SqlRS/DSC_SqlRS.psm1 index 24df7fb21c..6d6b59dafe 100644 --- a/source/DSCResources/DSC_SqlRS/DSC_SqlRS.psm1 +++ b/source/DSCResources/DSC_SqlRS/DSC_SqlRS.psm1 @@ -296,6 +296,14 @@ function Set-TargetResource } $reportingServicesServiceName = $reportingServicesData.Configuration.ServiceName + + if ( [System.String]::IsNullOrEmpty($reportingServicesServiceName) ) + { + $errorMessage = $script:localizedData.ServiceNameIsNullOrEmpty -f $InstanceName + + New-InvalidOperationException -Message $errorMessage + } + $reportingServicesDatabaseName = 'ReportServer' } elseif ( $InstanceName -eq 'MSSQLSERVER' ) diff --git a/source/DSCResources/DSC_SqlRS/en-US/DSC_SqlRS.strings.psd1 b/source/DSCResources/DSC_SqlRS/en-US/DSC_SqlRS.strings.psd1 index ed937fa250..74210a476c 100644 --- a/source/DSCResources/DSC_SqlRS/en-US/DSC_SqlRS.strings.psd1 +++ b/source/DSCResources/DSC_SqlRS/en-US/DSC_SqlRS.strings.psd1 @@ -6,4 +6,5 @@ ConvertFrom-StringData @' GetConfiguration = Get the current reporting services configuration for the instance '{0}'. RestartToFinishInitialization = Restarting Reporting Services to finish initialization. WaitingForServiceReady = Waiting {0} seconds for Reporting Services to be fully ready after restart. (DSC_SQLRS0001) + ServiceNameIsNullOrEmpty = The Configuration.ServiceName property is null or empty for SQL Server Reporting Services instance '{0}'. This property is required to determine the service name for SQL Server version 14 and higher. (DSC_SQLRS0002) '@ diff --git a/tests/Unit/DSC_SqlRS.Tests.ps1 b/tests/Unit/DSC_SqlRS.Tests.ps1 index c4af0ff2c4..6a1b15330b 100644 --- a/tests/Unit/DSC_SqlRS.Tests.ps1 +++ b/tests/Unit/DSC_SqlRS.Tests.ps1 @@ -693,6 +693,80 @@ Describe 'SqlRS\Set-TargetResource' -Tag 'Set' { } } } + + Context 'When Configuration.ServiceName is null or empty for SQL Server version 14 and higher' { + BeforeAll { + $mockDynamicIsInitialized = $false + + $mockGetCimInstance_ConfigurationSetting_ServiceNameNull = { + return @( + ( + New-Object -TypeName Microsoft.Management.Infrastructure.CimInstance -ArgumentList @( + 'MSReportServer_ConfigurationSetting' + 'root/Microsoft/SQLServer/ReportServer/RS_SQL2016/v14/Admin' + ) | Add-Member -MemberType NoteProperty -Name 'DatabaseServerName' -Value "$mockReportingServicesDatabaseServerName\$mockReportingServicesDatabaseNamedInstanceName" -PassThru | + Add-Member -MemberType NoteProperty -Name 'IsInitialized' -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name 'InstanceName' -Value $mockNamedInstanceName -PassThru | + Add-Member -MemberType NoteProperty -Name 'VirtualDirectoryReportServer' -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name 'VirtualDirectoryReportManager' -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name 'SecureConnectionLevel' -Value $mockDynamicSecureConnectionLevel -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'ServiceName' -Value $null -PassThru -Force + ) + ) + } + + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = (& $mockGetCimInstance_ConfigurationSetting_ServiceNameNull)[0] + ReportsApplicationName = 'ReportServerWebApp' + SqlVersion = 14 + } + } + + Mock -CommandName Get-CimInstance ` + -MockWith $mockGetCimInstance_Language ` + -ParameterFilter $mockGetCimInstance_OperatingSystem_ParameterFilter + } + + It 'Should throw the correct error message when ServiceName is null' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockDefaultParameters = @{ + InstanceName = $mockNamedInstanceName + DatabaseServerName = $mockReportingServicesDatabaseServerName + DatabaseInstanceName = $mockReportingServicesDatabaseNamedInstanceName + } + + { Set-TargetResource @mockDefaultParameters } | Should -Throw -ExpectedMessage ('*' + ($script:localizedData.ServiceNameIsNullOrEmpty -f $mockNamedInstanceName)) + } + } + + It 'Should throw the correct error message when ServiceName is empty' { + Mock -CommandName Get-ReportingServicesData -MockWith { + return @{ + Configuration = New-Object -TypeName Microsoft.Management.Infrastructure.CimInstance -ArgumentList @( + 'MSReportServer_ConfigurationSetting' + 'root/Microsoft/SQLServer/ReportServer/RS_SQL2016/v14/Admin' + ) | Add-Member -MemberType NoteProperty -Name 'ServiceName' -Value '' -PassThru -Force + ReportsApplicationName = 'ReportServerWebApp' + SqlVersion = 14 + } + } + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockDefaultParameters = @{ + InstanceName = $mockNamedInstanceName + DatabaseServerName = $mockReportingServicesDatabaseServerName + DatabaseInstanceName = $mockReportingServicesDatabaseNamedInstanceName + } + + { Set-TargetResource @mockDefaultParameters } | Should -Throw -ExpectedMessage ('*' + ($script:localizedData.ServiceNameIsNullOrEmpty -f $mockNamedInstanceName)) + } + } + } } Context "When configuring a named instance that are already initialized ()" {