Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SqlRS: Fails when SQL Instance and RS Instance Are Different #1868

Closed
shurick81 opened this issue Mar 8, 2023 · 33 comments · Fixed by #1870
Closed

SqlRS: Fails when SQL Instance and RS Instance Are Different #1868

shurick81 opened this issue Mar 8, 2023 · 33 comments · Fixed by #1870
Labels
bug The issue is a bug. good first issue The issue should be easier to fix and can be taken up by a beginner to learn to contribute on GitHub

Comments

@shurick81
Copy link
Contributor

Problem description

When we try to run SqlRS to configure, we get failure.

The issue might be related to the fact that use separate DBENGINE and RS instances. For example, DBENGINE instance is called "SQLInstance01" and RS instance is called "RSInstance01".

Here are test results for different SqlServerDsc versions:

14.2.1 works
15.2.0 works
16.0.0 fails
16.1.0 fails

So it looks like it stopped working since 16.0.0 release.

Verbose logs

VERBOSE: [SWAZSRV00]: LCM:  [ Start  Set      ]
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Resource ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Test     ]  [[SqlRS]ReportingServicesConfig]
Cannot bind argument to parameter 'ReferenceObject' because it is null.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Get the current reporting services
    + CategoryInfo          : InvalidData: (:) [], CimException
configuration for the instance 'RSInstance01'.
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObje
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
   ctCommand
CimInstances' with following parameters, ''namespaceName' =
    + PSComputerName        : SWAZSRV00
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
The PowerShell DSC resource '[SqlRS]ReportingServicesConfig' with SourceInfo
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Reporting services
'C:\Users\custom3094857\common\rsconfig-legacy.ps1::23::13::SqlRS' threw one or more non-terminating errors while
SWAZSRV00\SQLInstance01 are not initialized.
VERBOSE: [SWAZSRV00]: LCM:  [ End    Test     ]  [[SqlRS]ReportingServicesConfig]  in 1.2810 seconds.
running the Test-TargetResource functionality. These errors are logged to the ETW channel called
Microsoft-Windows-DSC/Operational. Refer to this channel for more details.
    + CategoryInfo          : InvalidOperation: (:) [], CimException
    + FullyQualifiedErrorId : NonTerminatingErrorFromProvider
    + PSComputerName        : SWAZSRV00

DSC configuration

Import-DscResource -ModuleName SqlServerDsc -ModuleVersion 16.1.0

SqlRS ReportingServicesConfig
{
    InstanceName            = 'RSInstance01'
    DatabaseServerName      = $env:COMPUTERNAME
    DatabaseInstanceName    = "SQLInstance01"
    ReportServerReservedUrl = @( 'http://+:80' )
    PsDscRunAsCredential    = $DomainAdminCredential
}

Suggested solution

I don't have

SQL Server edition and version

PS C:\Users\custom3094857> Invoke-Sqlcmd -ServerInstance $env:COMPUTERNAME\SQLInstance01 -Query "select @@version" | fl


Column1 : Microsoft SQL Server 2016 (SP2-CU17) (KB5001092) - 13.0.5888.11 (X64)
                Mar 19 2021 19:41:38
                Copyright (c) Microsoft Corporation
                Developer Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: ) (Hypervisor)

SQL Server PowerShell modules

Name      Version    Path
----      -------    ----
SqlServer 21.1.18226 C:\Program Files\WindowsPowerShell\Modules\SqlServer\21.1.18226\SqlServer.psd1
SQLPS     1.0        C:\Program Files (x86)\Microsoft SQL Server\130\Tools\PowerShell\Modules\SQLPS\SQLPS.psd1

Operating system

OsName               : Microsoft Windows Server 2016 Datacenter
OsOperatingSystemSKU : DatacenterServerEdition
OsArchitecture       : 64-bit
WindowsBuildLabEx    : 14393.5648.amd64fre.rs1_release.230105-1654
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

PowerShell version

Name                           Value
----                           -----
PSVersion                      5.1.14393.5582
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.5582
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

SqlServerDsc version

Name         Version Path
----         ------- ----
SqlServerDsc 16.1.0  C:\Program Files\WindowsPowerShell\Modules\SqlServerDsc\16.1.0\SqlServerDsc.psd1
SqlServerDsc 14.2.1  C:\Program Files\WindowsPowerShell\Modules\SqlServerDsc\14.2.1\SqlServerDsc.psd1
@johlju
Copy link
Member

johlju commented Mar 8, 2023

This is strange because the integration tests are using different instances too.

SqlRS 'Integration_Test'
{
# Instance name for the Reporting Services.
InstanceName = $Node.InstanceName
<#
Instance for Reporting Services databases.
Note: This instance is created in a prior integration test.
#>
DatabaseServerName = $Node.DatabaseServerName
DatabaseInstanceName = $Node.DatabaseInstanceName
Encrypt = 'Optional'
PsDscRunAsCredential = New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList @(
$Node.RunAs_UserName, (ConvertTo-SecureString -String $Node.RunAs_Password -AsPlainText -Force))
}

@johlju johlju added the needs investigation The issue needs to be investigated by the maintainers or/and the community. label Mar 8, 2023
@johlju
Copy link
Member

johlju commented Mar 8, 2023

It must fail on this row in Test-methid because the value returned for the current state is $null

ReferenceObject = $currentConfig.ReportServerReservedUrl

Though, not sure why older version works because this hasn't change in the time the resource has been named SqlRS.

Can you confirm it fails on that line?

@johlju johlju added needs more information The issue needs more information from the author or the community. and removed needs investigation The issue needs to be investigated by the maintainers or/and the community. labels Mar 8, 2023
@shurick81
Copy link
Contributor Author

@johlju how could I confirm that?

@johlju
Copy link
Member

johlju commented Mar 8, 2023

The easiest I would do is to add a Write-Verbose before the above line:

Write-Verbose -Message ($null -eq $currentConfig.ReportServerReservedUrl) -Verbose

@shurick81
Copy link
Contributor Author

Thanks for clarification!

I set this content https://gist.github.com/shurick81/b99631fef89e8da18a6e5de7a7f5c2b2 to C:\Program Files\WindowsPowerShell\Modules\SqlServerDsc\16.1.0\DSCResources\DSC_SqlRS\DSC_SqlRS.psm1 and I get the following output:

VERBOSE: [SWAZSRV00]: LCM:  [ Start  Resource ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Test     ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Get the current reporting services
configuration for the instance 'RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' =
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Reporting services
SWAZSRV00\SQLInstance01 are not initialized.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] True
Cannot bind argument to parameter 'ReferenceObject' because it is null.
    + CategoryInfo          : InvalidData: (:) [], CimException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObje
   ctCommand
    + PSComputerName        : SWAZSRV00

VERBOSE: [SWAZSRV00]: LCM:  [ End    Test     ]  [[SqlRS]ReportingServicesConfig]  in 0.8120 seconds.
The PowerShell DSC resource '[SqlRS]ReportingServicesConfig' with SourceInfo '::23::13::SqlRS' threw one or more
non-terminating errors while running the Test-TargetResource functionality. These errors are logged to the ETW channel
called Microsoft-Windows-DSC/Operational. Refer to this channel for more details.
    + CategoryInfo          : InvalidOperation: (:) [], CimException
    + FullyQualifiedErrorId : NonTerminatingErrorFromProvider
    + PSComputerName        : SWAZSRV00

Then I set the content of https://gist.github.com/shurick81/2dab56f7dcd3247f43ee5fba59b5f6e9 to C:\Program Files\WindowsPowerShell\Modules\SqlServerDsc\15.2.0\DSCResources\DSC_SqlRS\DSC_SqlRS.psm1 and I get the following output:

VERBOSE: [SWAZSRV00]: LCM:  [ Start  Resource ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Test     ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Get the current reporting services
configuration for the instance 'RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' =
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Reporting services
SWAZSRV00\SQLInstance01 are not initialized.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] False
VERBOSE: [SWAZSRV00]: LCM:  [ End    Test     ]  [[SqlRS]ReportingServicesConfig]  in 0.7340 seconds.
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Set      ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' =
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' = root/cimv2,'className' = Win32_OperatingSystem'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Initializing Reporting Services on
SWAZSRV00\SQLInstance01.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Setting report server virtual
directory on SWAZSRV00\SQLInstance01 to ReportServer_RSInstance01.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = SetVirtualDirectory,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Adding report server URL reservation
on SWAZSRV00\SQLInstance01: http://+:80.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = ReserveUrl,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Setting reports virtual directory on
SWAZSRV00\SQLInstance01 to ReportServer_RSInstance01.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = SetVirtualDirectory,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Adding reports URL reservation on
SWAZSRV00\SQLInstance01: http://+:80.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod' with following
parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName = "RSINSTANCE01"),'methodName' = ReserveUrl,'namespaceName' =
 root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod' with following
parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName = "RSINSTANCE01"),'methodName' =
GenerateDatabaseCreationScript,'namespaceName' = root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate CimInstances' with
following parameters, ''namespaceName' = root\cimv2,'className' = Win32_Service'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod' with following
parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName = "RSINSTANCE01"),'methodName' =
GenerateDatabaseRightsScript,'namespaceName' = root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Preferred module SqlServer found. (SQLCOMMON0023)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Importing PowerShell module 'SqlServer' with version
'21.1.18226' from path 'C:\Program Files\WindowsPowerShell\Modules\SqlServer\21.1.18226\SqlServer.psm1'. (SQLCOMMON0025)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'msdb'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'master'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'master'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'msdb'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Caution: Changing any part of an object name could
break scripts and stored procedures.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Caution: Changing any part of an object name could
break scripts and stored procedures.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] The module 'CreateRdlChunk' depends on the missing
object 'CreateSegmentedChunk'. The module will still be created; however, it cannot run successfully until the object exists.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] The module 'CreateRdlChunk' depends on the missing
object 'CreateChunkSegment'. The module will still be created; however, it cannot run successfully until the object exists.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'master'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'msdb'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'master'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod' with following
parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName = "RSINSTANCE01"),'methodName' =
SetDatabaseConnection,'namespaceName' = root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate CimInstances' with
following parameters, ''namespaceName' = root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' =
MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Restarting Reporting Services.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Getting information about service
'ReportServer$RSInstance01'. (SQLCOMMON0037)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] 'SQL Server Reporting Services (RSINSTANCE01)' service
is restarting. (SQLCOMMON0038)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] 'SQL Server Reporting Services (RSINSTANCE01)' service
is stopping. (SQLCOMMON0039)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Waiting 30 seconds before starting service 'SQL Server
Reporting Services (RSINSTANCE01)'. (SQLCOMMON0041)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] 'SQL Server Reporting Services (RSINSTANCE01)' service
is starting. (SQLCOMMON0040)
WARNING: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Waiting for service 'SQL Server Reporting Services
(RSINSTANCE01) (ReportServer$RSInstance01)' to start...
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Get the current reporting services configuration for
the instance 'RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate CimInstances' with
following parameters, ''namespaceName' = root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' =
MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod' with following
parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName = "RSINSTANCE01"),'methodName' =
ListReservedUrls,'namespaceName' = root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod' complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] False
VERBOSE: [SWAZSRV00]: LCM:  [ End    Set      ]  [[SqlRS]ReportingServicesConfig]  in 118.5910 seconds.
VERBOSE: [SWAZSRV00]: LCM:  [ End    Resource ]  [[SqlRS]ReportingServicesConfig]

@johlju
Copy link
Member

johlju commented Mar 9, 2023

So it returns $null (outputs True) in v16.1, but have a value, probably empty string, (outputs False) in v15.2.

Looking at your gist of 16.1 it sets it to $null here: https://gist.github.com/shurick81/b99631fef89e8da18a6e5de7a7f5c2b2#file-dsc_sqlrs-psm1-L60-L71
The difference in 15.2 is that it is not set to $null, but rather set to a variable that has no assigned value (which should be $null too). Very strange it behaves like this.

But the bug is that Test-TargetResource must handle $null correctly.

This code:

$compareParameters = @{
ReferenceObject = $currentConfig.ReportServerReservedUrl
DifferenceObject = $ReportServerReservedUrl
}
if (($null -ne $ReportServerReservedUrl) -and ($null -ne (Compare-Object @compareParameters)))
{
Write-Verbose -Message "Report server reserved URLs on $DatabaseServerName\$DatabaseInstanceName are $($currentConfig.ReportServerReservedUrl -join ', '), should be $($ReportServerReservedUrl -join ', ')."
$result = $false
}
$compareParameters = @{
ReferenceObject = $currentConfig.ReportsReservedUrl
DifferenceObject = $ReportsReservedUrl
}
if (($null -ne $ReportsReservedUrl) -and ($null -ne (Compare-Object @compareParameters)))
{
Write-Verbose -Message "Reports reserved URLs on $DatabaseServerName\$DatabaseInstanceName are $($currentConfig.ReportsReservedUrl -join ', ')), should be $($ReportsReservedUrl -join ', ')."
$result = $false
}

Should be changed to something like this:

if ($PSBoundParameters.ContainsKey('ReportServerReservedUrl'))
    {
        if ($null -eq $currentConfig.ReportServerReservedUrl)
        {
            Write-Verbose -Message "Report server reserved URLs on $DatabaseServerName\$DatabaseInstanceName are missing, should be $($ReportServerReservedUrl -join ', ')."
            $result = $false
        }
        else
        {
            $compareParameters = @{
                ReferenceObject  = $currentConfig.ReportServerReservedUrl
                DifferenceObject = $ReportServerReservedUrl
            }

            if ($null -ne (Compare-Object @compareParameters))
            {
                Write-Verbose -Message "Report server reserved URLs on $DatabaseServerName\$DatabaseInstanceName are $($currentConfig.ReportServerReservedUrl -join ', '), should be $($ReportServerReservedUrl -join ', ')."
                $result = $false
            }
        }
    }

    if ($PSBoundParameters.ContainsKey('ReportsReservedUrl'))
    {
        if ($null -eq $currentConfig.ReportServerReservedUrl)
        {
            Write-Verbose -Message "Reports reserved URLs on $DatabaseServerName\$DatabaseInstanceName are missing, should be $($ReportsReservedUrl -join ', ')."
            $result = $false
        }
        else
        {
            $compareParameters = @{
                ReferenceObject  = $currentConfig.ReportsReservedUrl
                DifferenceObject = $ReportsReservedUrl
            }

            if ($null -ne (Compare-Object @compareParameters))
            {
                Write-Verbose -Message "Reports reserved URLs on $DatabaseServerName\$DatabaseInstanceName are $($currentConfig.ReportsReservedUrl -join ', ')), should be $($ReportsReservedUrl -join ', ')."
                $result = $false
            }
        }
    }

@johlju johlju added bug The issue is a bug. help wanted The issue is up for grabs for anyone in the community. good first issue The issue should be easier to fix and can be taken up by a beginner to learn to contribute on GitHub and removed needs more information The issue needs more information from the author or the community. labels Mar 9, 2023
@shurick81
Copy link
Contributor Author

So what's the next step? I can try the code you suggest with 16.1.0 @johlju

@johlju
Copy link
Member

johlju commented Mar 9, 2023

If you can confirm it works with the proposed code it would be great.

Next step is to send in a PR to propose the change, and also add a unit test that fails with current implementation and passes with the suggest change.

I won't have time to look at it in the near future, so if you (or someone else) have time, please send in a PR.

@shurick81
Copy link
Contributor Author

When I set this contents https://gist.github.com/shurick81/e76065f2748288943bacd0f69d40f77c to C:\Program Files\WindowsPowerShell\Modules\SqlServerDsc\16.1.0\DSCResources\DSC_SqlRS\DSC_SqlRS.psm1 I get the following output:

VERBOSE: [SWAZSRV00]: LCM:  [ Start  Resource ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Test     ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Get the current reporting services
configuration for the instance 'RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' =
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Reporting services
SWAZSRV00\SQLInstance01 are not initialized.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Report server reserved URLs on
SWAZSRV00\SQLInstance01 are missing, should be http://+:80.
VERBOSE: [SWAZSRV00]: LCM:  [ End    Test     ]  [[SqlRS]ReportingServicesConfig]  in 0.8120 seconds.
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Set      ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' =
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' = root/cimv2,'className' = Win32_OperatingSystem'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Initializing Reporting Services on
SWAZSRV00\SQLInstance01.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Setting report server virtual
directory on SWAZSRV00\SQLInstance01 to 'ReportServer_RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = SetVirtualDirectory,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Adding report server URL reservation
on SWAZSRV00\SQLInstance01: http://+:80.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = ReserveUrl,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Setting reports virtual directory on
SWAZSRV00\SQLInstance01 to 'ReportServer_RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = SetVirtualDirectory,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Adding reports URL reservation on
SWAZSRV00\SQLInstance01: http://+:80.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = ReserveUrl,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Generate database creation script on
SWAZSRV00\SQLInstance01 for database 'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = GenerateDatabaseCreationScript,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' = root\cimv2,'className' = Win32_Service'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Generate database rights script on
SWAZSRV00\SQLInstance01 for database 'ReportServer$RSInstance01' and user 'C0NT0S00\_ssrs'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = GenerateDatabaseRightsScript,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'msdb'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'master'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'master'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'msdb'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Caution: Changing any part of an
object name could break scripts and stored procedures.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Caution: Changing any part of an
object name could break scripts and stored procedures.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] The module 'CreateRdlChunk' depends
on the missing object 'CreateSegmentedChunk'. The module will still be created; however, it cannot run successfully
until the object exists.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] The module 'CreateRdlChunk' depends
on the missing object 'CreateChunkSegment'. The module will still be created; however, it cannot run successfully until
 the object exists.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'master'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01TempDB'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'msdb'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to 'master'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Changed database context to
'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Set database connection on
SWAZSRV00\SQLInstance01 to database 'ReportServer$RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = SetDatabaseConnection,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Restarting Reporting Services to
finish initialization.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Getting information about service
'ReportServer$RSInstance01'. (SQLCOMMON0037)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] 'SQL Server Reporting Services
(RSINSTANCE01)' service is restarting. (SQLCOMMON0038)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] 'SQL Server Reporting Services
(RSINSTANCE01)' service is stopping. (SQLCOMMON0039)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Waiting 30 seconds before starting
service 'SQL Server Reporting Services (RSINSTANCE01)'. (SQLCOMMON0041)
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] 'SQL Server Reporting Services
(RSINSTANCE01)' service is starting. (SQLCOMMON0040)
WARNING: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Waiting for service 'SQL Server
Reporting Services (RSINSTANCE01) (ReportServer$RSInstance01)' to start...
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' =
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Reporting Services on
SWAZSRV00\SQLInstance01 is initialized.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Get the current reporting services
configuration for the instance 'RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' =
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Invoke CimMethod'
with following parameters, ''instance' = MSReportServer_ConfigurationSetting (InstanceName =
"RSINSTANCE01"),'methodName' = ListReservedUrls,'namespaceName' =
root/Microsoft/SQLServer/ReportServer/RS_RSInstance01/v13/Admin'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Invoke CimMethod'
complete.
VERBOSE: [SWAZSRV00]: LCM:  [ End    Set      ]  [[SqlRS]ReportingServicesConfig]  in 118.3690 seconds.
VERBOSE: [SWAZSRV00]: LCM:  [ End    Resource ]  [[SqlRS]ReportingServicesConfig]

@shurick81
Copy link
Contributor Author

I can come up with a PR and update the DSC_SqlRS.psm1 but I'm not sure I'm ready for updating the tests. Probably it will need learning the structure of the tests first.

@johlju
Copy link
Member

johlju commented Mar 9, 2023

I think you could copy the block here, to a new block just after.

Context 'When Report Server virtual directory is different' {
BeforeAll {
Mock -CommandName Get-TargetResource -MockWith {
return @{
IsInitialized = $true
ReportServerVirtualDirectory = 'ReportServer_SQL2016'
ReportsVirtualDirectory = 'Reports_SQL2016'
}
}
}
It 'Should return state as not in desired state' {
InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0
$testParameters = @{
InstanceName = 'INSTANCE'
DatabaseServerName = 'DBSERVER'
DatabaseInstanceName = 'DBINSTANCE'
ReportServerVirtualDirectory = 'ReportServer_SQL2016'
ReportsVirtualDirectory = 'Reports_NewName'
}
$resultTestTargetResource = Test-TargetResource @testParameters
$resultTestTargetResource | Should -BeFalse
}
}
}

Then change the new block to something like this:

        Context 'When current Report Server virtual directory is $null' {
            BeforeAll {
                Mock -CommandName Get-TargetResource -MockWith {
                    return @{
                        IsInitialized                = $true
                        ReportServerVirtualDirectory = $null
                    }
                }
            }

            It 'Should return state as not in desired state' {
                InModuleScope -ScriptBlock {
                    Set-StrictMode -Version 1.0

                    $testParameters = @{
                        InstanceName                 = 'INSTANCE'
                        DatabaseServerName           = 'DBSERVER'
                        DatabaseInstanceName         = 'DBINSTANCE'
                        ReportServerVirtualDirectory = 'ReportServer_SQL2016'
                    }

                    $resultTestTargetResource = Test-TargetResource @testParameters

                    $resultTestTargetResource | Should -BeFalse
                }
            }
        }

Then another one that tests $null for ReportsVirtualDirectory too.

those test should fail with the current implementation, and work with the proposed change. Although, not certain as I just made it from the top of my head.

@shurick81
Copy link
Contributor Author

@johlju then I guess you want me to run these tests somehow locally before committing to the PR?

@johlju
Copy link
Member

johlju commented Mar 9, 2023

After you clone the repo you run (in the repo folder):

./build.ps1 -ResolveDependency -Tasks noop

The above is just needed once. Then you run the following to build the module:

./build.ps1 -Tasks build

After that you can run the unit test by running:

Invoke-Pester ./tests/Unit/DSC_SqlRS.Tests.ps1 -Output Detailed

It is also possible running the individual test through the build script (the pipeline). But it is usually bulkier than just doing Invoke-Pester.

./build.ps1 -Tasks test -PesterScript ./tests/Unit/DSC_SqlRS.Tests.ps1 -CodeCoverageThreshold 0

After you see the tests pass above you add the new test I suggested and run the test again to see that they fail. Then add the code changes, run the build task again, then run the tests a third time to see all tests pass.

Hope it works... 🙂

@shurick81
Copy link
Contributor Author

I guess I need to have some prerequisites installed, like even Pester? Maybe there is some simple way of running tests in a Windows container where I could temporary install Pester and other prerequisites for running tests?

@johlju
Copy link
Member

johlju commented Mar 10, 2023

When you run ResolveDependencies as shown above it will download all prerequisite into a ./output/RequiredModules. All that is needed will be inside the local repo folder, and it will not change your machine.
Removing the local repo folder will remove everything that was downloaded.

The build script setups up the PowerShell session so the pipeline can be run, but closing the session and opening a new then everything is back to normal. So for each session opened, if you want to run tests for example, the minimum requirement is to run ./build.ps1 -Tasks noop that will modify the session.

@shurick81
Copy link
Contributor Author

I think you could copy the block here, to a new block just after.

Context 'When Report Server virtual directory is different' {
BeforeAll {
Mock -CommandName Get-TargetResource -MockWith {
return @{
IsInitialized = $true
ReportServerVirtualDirectory = 'ReportServer_SQL2016'
ReportsVirtualDirectory = 'Reports_SQL2016'
}
}
}
It 'Should return state as not in desired state' {
InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0
$testParameters = @{
InstanceName = 'INSTANCE'
DatabaseServerName = 'DBSERVER'
DatabaseInstanceName = 'DBINSTANCE'
ReportServerVirtualDirectory = 'ReportServer_SQL2016'
ReportsVirtualDirectory = 'Reports_NewName'
}
$resultTestTargetResource = Test-TargetResource @testParameters
$resultTestTargetResource | Should -BeFalse
}
}
}

Then change the new block to something like this:

        Context 'When current Report Server virtual directory is $null' {
            BeforeAll {
                Mock -CommandName Get-TargetResource -MockWith {
                    return @{
                        IsInitialized                = $true
                        ReportServerVirtualDirectory = $null
                    }
                }
            }

            It 'Should return state as not in desired state' {
                InModuleScope -ScriptBlock {
                    Set-StrictMode -Version 1.0

                    $testParameters = @{
                        InstanceName                 = 'INSTANCE'
                        DatabaseServerName           = 'DBSERVER'
                        DatabaseInstanceName         = 'DBINSTANCE'
                        ReportServerVirtualDirectory = 'ReportServer_SQL2016'
                    }

                    $resultTestTargetResource = Test-TargetResource @testParameters

                    $resultTestTargetResource | Should -BeFalse
                }
            }
        }

Then another one that tests $null for ReportsVirtualDirectory too.

those test should fail with the current implementation, and work with the proposed change. Although, not certain as I just made it from the top of my head.

When we mock it, why do we want IsInitialized = $true. I guess when I first experienced the issue with SqlRS, I did not have this service initialized... I mean there was no service configured, no RS database, etc. Or maybe IsInitialized means something different @johlju ?

@johlju
Copy link
Member

johlju commented Mar 11, 2023

In this case I think it should be $false. It was just an example, so change it as required.

@shurick81
Copy link
Contributor Author

I'm trying to get my head around how we write the tests in the way that they fail when we have issues with the code. Should they even fail with the 16.1.0 codebase? I guess the reason to write the tests is that they fail and indicate something for us in the future :)

@shurick81
Copy link
Contributor Author

added these tests:

        Context 'When current Report Server virtual directory is $null' {
            BeforeAll {
                Mock -CommandName Get-TargetResource -MockWith {
                    return @{
                        IsInitialized                = $true
                        ReportServerVirtualDirectory = $null
                        ReportsVirtualDirectory      = 'Reports_SQL2016'
                    }
                }
            }

            It 'Should return state as not in desired state' {
                InModuleScope -ScriptBlock {
                    Set-StrictMode -Version 1.0

                    $testParameters = @{
                        InstanceName                 = 'INSTANCE'
                        DatabaseServerName           = 'DBSERVER'
                        DatabaseInstanceName         = 'DBINSTANCE'
                        ReportServerVirtualDirectory = 'ReportServer_SQL2016'
                        ReportsVirtualDirectory      = 'Reports_SQL2016'
                    }

                    $resultTestTargetResource = Test-TargetResource @testParameters

                    $resultTestTargetResource | Should -BeFalse
                }
            }
        }

        Context 'When current Reports virtual directory is $null' {
            BeforeAll {
                Mock -CommandName Get-TargetResource -MockWith {
                    return @{
                        IsInitialized                = $true
                        ReportServerVirtualDirectory = 'ReportServer_SQL2016'
                        ReportsVirtualDirectory      = $null
                    }
                }
            }

            It 'Should return state as not in desired state' {
                InModuleScope -ScriptBlock {
                    Set-StrictMode -Version 1.0

                    $testParameters = @{
                        InstanceName                 = 'INSTANCE'
                        DatabaseServerName           = 'DBSERVER'
                        DatabaseInstanceName         = 'DBINSTANCE'
                        ReportServerVirtualDirectory = 'ReportServer_SQL2016'
                        ReportsVirtualDirectory      = 'Reports_SQL2016'
                    }

                    $resultTestTargetResource = Test-TargetResource @testParameters

                    $resultTestTargetResource | Should -BeFalse
                }
            }
        }

        Context 'When both current Reports virtual directory and Report Server virtual directory are $null' {
            BeforeAll {
                Mock -CommandName Get-TargetResource -MockWith {
                    return @{
                        IsInitialized                = $false
                        ReportServerVirtualDirectory = $null
                        ReportsVirtualDirectory      = $null
                    }
                }
            }

            It 'Should return state as not in desired state' {
                InModuleScope -ScriptBlock {
                    Set-StrictMode -Version 1.0

                    $testParameters = @{
                        InstanceName                 = 'INSTANCE'
                        DatabaseServerName           = 'DBSERVER'
                        DatabaseInstanceName         = 'DBINSTANCE'
                        ReportServerVirtualDirectory = 'ReportServer_SQL2016'
                        ReportsVirtualDirectory      = 'Reports_SQL2016'
                    }

                    $resultTestTargetResource = Test-TargetResource @testParameters

                    $resultTestTargetResource | Should -BeFalse
                }
            }
        }

I get the following output on them, even from main branch:

  Context When current Report Server virtual directory is $null
    [+] Should return state as not in desired state 42ms (39ms|3ms)
  Context When current Reports virtual directory is $null
    [+] Should return state as not in desired state 21ms (18ms|3ms)
  Context When both current Reports virtual directory and Report Server virtual directory are $null
    [+] Should return state as not in desired state 21ms (19ms|2ms)

@johlju
Copy link
Member

johlju commented Mar 11, 2023

I'm trying to get my head around how we write the tests in the way that they fail when we have issues with the code. Should they even fail with the 16.1.0 codebase?

Yes, it should fail the the code in the main branch. In this case we could leverage TDD (test-driven development).

The test you write should fail with the same error as you saw when you run your configuration.
By assigning $null to the property that cause the error to happened. But we need to mock everything correctly before that so we end up in the same code path. I was hoping that the code I suggested would do that.

When you then add the code change to handle the $null value the tests should pass.

@johlju
Copy link
Member

johlju commented Mar 11, 2023

I will see if I have some time tomorrow to give some more suggestions.

@shurick81
Copy link
Contributor Author

shurick81 commented Mar 11, 2023

Also, when I run Test-DscConfiguration it returns False even in 16.1.0 version:

03/11/2023 16:54:52 Compiling DSC


    Directory: C:\Users\custom3094857\RSConfig


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        3/11/2023   4:54 PM           4576 SWAZSRV00.mof


PS C:\Users\custom3094857> Test-DscConfiguration $configName -Verbose;
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = TestConfiguration,'className'
= MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer SWAZSRV00 with user sid
S-1-5-21-3778753948-4178554416-3554844925-500.
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Compare  ]
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Resource ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]: LCM:  [ Start  Test     ]  [[SqlRS]ReportingServicesConfig]
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Get the current reporting services
configuration for the instance 'RSInstance01'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Perform operation 'Enumerate
CimInstances' with following parameters, ''namespaceName' =
root\Microsoft\SQLServer\ReportServer\RS_RSInstance01\v13\Admin,'className' = MSReportServer_ConfigurationSetting'.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Operation 'Enumerate CimInstances'
complete.
VERBOSE: [SWAZSRV00]:                            [[SqlRS]ReportingServicesConfig] Reporting services
SWAZSRV00\SQLInstance01 are not initialized.
Cannot bind argument to parameter 'ReferenceObject' because it is null.
    + CategoryInfo          : InvalidData: (:) [], CimException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObje
   ctCommand
    + PSComputerName        : SWAZSRV00

VERBOSE: [SWAZSRV00]: LCM:  [ End    Test     ]  [[SqlRS]ReportingServicesConfig] False in 0.8440 seconds.
VERBOSE: [SWAZSRV00]: LCM:  [ *FAILED*Compare  ]     Completed processing compare operation. The operation returned
False.
The PowerShell DSC resource '[SqlRS]ReportingServicesConfig' with SourceInfo '::23::13::SqlRS' threw one or more
non-terminating errors while running the Test-TargetResource functionality. These errors are logged to the ETW channel
called Microsoft-Windows-DSC/Operational. Refer to this channel for more details.
    + CategoryInfo          : InvalidOperation: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : NonTerminatingErrorFromProvider
    + PSComputerName        : SWAZSRV00

VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 1.495 seconds

But it also throws errors:

image

maybe we should somehow make tests like

It 'Should return state as not in desired state but not throw errors'

@shurick81
Copy link
Contributor Author

This is strange because the integration tests are using different instances too.

SqlRS 'Integration_Test'
{
# Instance name for the Reporting Services.
InstanceName = $Node.InstanceName
<#
Instance for Reporting Services databases.
Note: This instance is created in a prior integration test.
#>
DatabaseServerName = $Node.DatabaseServerName
DatabaseInstanceName = $Node.DatabaseInstanceName
Encrypt = 'Optional'
PsDscRunAsCredential = New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList @(
$Node.RunAs_UserName, (ConvertTo-SecureString -String $Node.RunAs_Password -AsPlainText -Force))
}

These integration tests, are they running in environment where reporting services are not configured?

shurick81 added a commit to shurick81/SqlServerDsc that referenced this issue Mar 11, 2023
@johlju
Copy link
Member

johlju commented Mar 12, 2023

I see now that the tests I suggest was using wrong properties, so that is why they did not throw an error.

Add these tests between the tests at line 1107.

        Context 'When current Report Server reserved URL is $null' {
            BeforeAll {
                Mock -CommandName Get-TargetResource -MockWith {
                    return @{
                        IsInitialized           = $false
                        ReportServerReservedUrl = $null
                    }
                }
            }

            It 'Should return state as not in desired state' {
                InModuleScope -ScriptBlock {
                    Set-StrictMode -Version 1.0

                    $testParameters = @{
                        InstanceName            = 'INSTANCE'
                        DatabaseServerName      = 'DBSERVER'
                        DatabaseInstanceName    = 'DBINSTANCE'
                        ReportServerReservedUrl = 'ReportServer_SQL2016'
                    }

                    $resultTestTargetResource = Test-TargetResource @testParameters

                    $resultTestTargetResource | Should -BeFalse
                }
            }
        }

        Context 'When current Reports reserved URL is $null' {
            BeforeAll {
                Mock -CommandName Get-TargetResource -MockWith {
                    return @{
                        IsInitialized      = $false
                        ReportsReservedUrl = $null
                    }
                }
            }

            It 'Should return state as not in desired state' {
                InModuleScope -ScriptBlock {
                    Set-StrictMode -Version 1.0

                    $testParameters = @{
                        InstanceName         = 'INSTANCE'
                        DatabaseServerName   = 'DBSERVER'
                        DatabaseInstanceName = 'DBINSTANCE'
                        ReportsReservedUrl   = 'Reports_SQL2016'
                    }

                    $resultTestTargetResource = Test-TargetResource @testParameters

                    $resultTestTargetResource | Should -BeFalse
                }
            }
        }

They return an exception when run on branch main.

Describing SqlRS\Test-TargetResource
 Context When the system is not in the desired state
  Context When Reporting Services are not initialized
    [+] Should return state as not in desired state 16ms (12ms|4ms)
  Context When current Report Server reserved URL is $null
    [-] Should return state as not in desired state 18ms (16ms|2ms)
     ParameterBindingValidationException: Cannot bind argument to parameter 'ReferenceObject' because it is null.
     at Test-TargetResource, C:\source\SqlServerDsc\output\builtModule\SqlServerDsc\16.2.0\DSCResources\DSC_SqlRS\DSC_SqlRS.psm1:961
     at <ScriptBlock>, C:\source\SqlServerDsc\tests\Unit\DSC_SqlRS.Tests.ps1:1129
  Context When current Reports reserved URL is $null
    [-] Should return state as not in desired state 30ms (28ms|1ms)
     ParameterBindingValidationException: Cannot bind argument to parameter 'ReferenceObject' because it is null.
     at Test-TargetResource, C:\source\SqlServerDsc\output\builtModule\SqlServerDsc\16.2.0\DSCResources\DSC_SqlRS\DSC_SqlRS.psm1:972
     at <ScriptBlock>, C:\source\SqlServerDsc\tests\Unit\DSC_SqlRS.Tests.ps1:1157
  Context When Report Server virtual directory is different
    [+] Should return state as not in desired state 10ms (8ms|1ms)
  Context When Reports virtual directory is different
    [+] Should return state as not in desired state 17ms (15ms|2ms)
  Context When Report Server Report Server reserved URLs is different
    [+] Should return state as not in desired state 8ms (6ms|1ms)
  Context When Report Server Reports reserved URLs is different
    [+] Should return state as not in desired state 8ms (6ms|2ms)
  Context When SSL is not used
    [+] Should return state as not in desired state 9ms (7ms|2ms)
 Context When the system is in the desired state
   [+] Should return state as in desired state 8ms (6ms|2ms)

@johlju
Copy link
Member

johlju commented Mar 12, 2023

Also, after applying the suggested change (and running build task) the new tests pass.

@johlju
Copy link
Member

johlju commented Mar 12, 2023

Added suggested changes to shurick81#1 since I already had the code written. 🙂 If you merge that (when you approve of the suggestions) your PR will be automatically updated.

@johlju johlju added in progress The issue is being actively worked on by someone. and removed help wanted The issue is up for grabs for anyone in the community. labels Mar 12, 2023
@johlju
Copy link
Member

johlju commented Mar 12, 2023

These integration tests, are they running in environment where reporting services are not configured?

Yes. The integration tests installs a new RS instance. Either by SqlSetup (SQL2016 and lower) or SqlRSSetup (SQL2017 and higher). Integration tests for SqlRS is then configuring the RS instance installed by the prior integration tests.

@shurick81
Copy link
Contributor Author

ok, so when I was writing tests I confused URL and directory, thanks for finding this out :)

shurick81 pushed a commit to shurick81/SqlServerDsc that referenced this issue Mar 12, 2023
johlju pushed a commit that referenced this issue Mar 19, 2023
…rl (#1870)

- SqlRS
  - Fixed issue of configuring reporting services (issue #1868).
@johlju johlju removed the in progress The issue is being actively worked on by someone. label Mar 19, 2023
@rachaelsingleton
Copy link

rachaelsingleton commented Mar 21, 2023

@johlju I'm using the updated version, but I still seem to be getting the same error. Am I missing something?

VERBOSE: [azRSBuild22SQL2]: LCM:  [ Start  Resource ]  [[SqlRS]ssrsConfig]
VERBOSE: [azRSBuild22SQL2]: LCM:  [ Start  Test     ]  [[SqlRS]ssrsConfig]
VERBOSE: [azRSBuild22SQL2]:                            [[SqlRS]ssrsConfig] Get the current reporting services configuration for the instance 'SSRS'.
VERBOSE: [azRSBuild22SQL2]:                            [[SqlRS]ssrsConfig] Perform operation 'Enumerate CimInstances' with following parameters, ''namespaceName' = root\Microsoft\SQLServer\ReportServer\RS_SSRS\v15\Admin,'classN
ame' = MSReportServer_ConfigurationSetting'.
VERBOSE: [azRSBuild22SQL2]:                            [[SqlRS]ssrsConfig] Operation 'Enumerate CimInstances' complete.
VERBOSE: [azRSBuild22SQL2]:                            [[SqlRS]ssrsConfig] Reporting services azRSBuild22SQL2\SSRS are not initialized.
VERBOSE: [azRSBuild22SQL2]:                            [[SqlRS]ssrsConfig] Report server virtual directory on azRSBuild22SQL2\SSRS is , should be ReportServer.
VERBOSE: [azRSBuild22SQL2]:                            [[SqlRS]ssrsConfig] Reports virtual directory on azRSBuild22SQL2\SSRS is , should be Reports.
Cannot bind argument to parameter 'ReferenceObject' because it is null.
    + CategoryInfo          : InvalidData: (:) [], CimException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObjectCommand
    + PSComputerName        : localhost
 
Cannot bind argument to parameter 'ReferenceObject' because it is null.
    + CategoryInfo          : InvalidData: (:) [], CimException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObjectCommand
    + PSComputerName        : localhost

Here's my config:

 SqlRS ssrsConfig
                {
                    InstanceName                 = 'SSRS'
                    DatabaseServerName           = $ComputerName    
                    DatabaseInstanceName         = 'SSRS'
                    ReportServerVirtualDirectory = 'ReportServer'
                    ReportsVirtualDirectory      = 'Reports'
                    ReportServerReservedUrl      = @('http://+:80')
                    ReportsReservedUrl           = @('http://+:80')
                    DependsOn = '[PendingReboot]ssrs'
                    PsDscRunAsCredential = $Cred
                }

@johlju
Copy link
Member

johlju commented Mar 21, 2023

@rachaelsingleton
Copy link

@johlju I did

@johlju
Copy link
Member

johlju commented Mar 21, 2023

Reopening this until I have the integration tests in the PR #1877 working, having issues with them unrelated to this.

@rachaelsingleton can you add the following:

Write-Verbose -Message ($null -eq $currentConfig.ReportServerReservedUrl | Out-String) -Verbose
Write-Verbose -Message ([System.String]::IsNullOrEmpty($currentConfig.ReportServerReservedUrl) | Out-String) -Verbose

Before this line in the module on your node:

if ($null -eq $currentConfig.ReportServerReservedUrl)

Also can you add the following:

Write-Verbose -Message ($null -eq $currentConfig.ReportsReservedUrl) | Out-String) -Verbose
Write-Verbose -Message ([System.String]::IsNullOrEmpty($currentConfig.ReportsReservedUrl)) | Out-String) -Verbose

Before this line in the module on your node:

if ($null -eq $currentConfig.ReportsReservedUrl)

The run the configuration again and let me know the verbose output.

@johlju johlju reopened this Mar 21, 2023
@johlju
Copy link
Member

johlju commented Mar 25, 2023

@rachaelsingleton did you have an opportunity to debug using the above suggestion? I have the integration tests passing in the PR #1877, so the change should have fixed it for your configuration too. 🤔 Closing this until I get more information.

@johlju johlju closed this as completed Mar 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug. good first issue The issue should be easier to fix and can be taken up by a beginner to learn to contribute on GitHub
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants