diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f4decbfaf..946e3ba96e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Public commands: + - `Install-SqlDscReportingService` + - `Install-SqlDscBIReportServer` + - `Repair-SqlDscReportingService` + - `Repair-SqlDscBIReportServer` + - `Uninstall-SqlDscReportingService` + - `Uninstall-SqlDscBIReportServer` - Private function: - `Invoke-ReportServerSetupAction` @@ -17,6 +24,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 now been moved to the WikiSource folder. The examples are published to the repository Wiki. The README has been updated to link to the new location ([issue #2051](https://github.com/dsccommunity/SqlServerDsc/issues/2051)). + - Integration test stages has been modified to split the testing into + several different areas. The tests are dependent on this order: + - Quality_Test_and_Unit_Test + - Integration_Test_Commands_SqlServer + - Integration_Test_Commands_ReportingServices + - Integration_Test_Commands_BIReportServer + - Integration_Test_Resources_SqlServer + - Integration_Test_Resources_SqlServer_dbatools + - Integration_Test_Resources_ReportingServices + - Integration_Test_Resources_ReportingServices_dbatools - SqlSetup - Fixed issue with AddNode where cluster IP information was not being passed to setup.exe ([issue #1171](https://github.com/dsccommunity/SqlServerDsc/issues/1171)). @@ -31,10 +48,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix localization strings in `Assert` method. - `Save-SqlDscSqlServerMediaFile` - Fix localizations strings that used wrong keys. - - Fix unit tests so the work cross-platform. + - Fix unit tests so they work cross-platform. - `Install-SqlDscServer` and private function `Invoke-SetupAction` - Fix localization string keys naming. - Fix unit tests to use correct localization string names. + - Remove redundant unit tests. - `SqlConfiguration` - Change the alias command to real command name, to pass HQRM tests. - `SqlDatabaseUser` @@ -55,7 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - SqlSetup - - Added new parameter ProductCoveredbySA which is introduced in SQL 2022. + - Added new parameter ProductCoveredBySA which is introduced in SQL 2022. ### Added diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9a9af04115..1040101eb2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -119,7 +119,6 @@ stages: testResultsFormat: 'NUnit' testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' testRunTitle: 'HQRM' - - job: Test_Unit displayName: 'Unit' pool: @@ -156,7 +155,6 @@ stages: targetPath: '$(buildFolderName)/$(testResultFolderName)/' artifactName: $(testArtifactName) parallel: true - - job: Code_Coverage displayName: 'Publish Code Coverage' dependsOn: Test_Unit @@ -193,9 +191,9 @@ stages: bash <(curl -s https://codecov.io/bash) -f "./$(buildFolderName)/$(testResultFolderName)/JaCoCo_coverage.xml" -F unit displayName: 'Publish Code Coverage to Codecov.io' - - stage: Integration_Test_Commands - displayName: 'Integration Test Commands' - dependsOn: Build + - stage: Integration_Test_Commands_SqlServer + displayName: 'Integration Test Commands - SQL Server' + dependsOn: Quality_Test_and_Unit_Test jobs: - job: Test_Integration displayName: 'Commands' @@ -269,9 +267,139 @@ stages: testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' testRunTitle: 'Integration Commands ($(TEST_CONFIGURATION) / $(JOB_VMIMAGE))' - - stage: Integration_Test_Resources - displayName: 'Integration Test Resources' - dependsOn: Build + - stage: Integration_Test_Commands_ReportingServices + displayName: 'Integration Test Commands - Reporting Services' + dependsOn: Integration_Test_Commands_SqlServer + jobs: + - job: Test_Integration + displayName: 'Commands' + strategy: + matrix: + SQL2017_WIN2019: + JOB_VMIMAGE: 'windows-2019' + TEST_CONFIGURATION: 'Integration_SQL2017' + SQL2017_WIN2022: + JOB_VMIMAGE: 'windows-2022' + TEST_CONFIGURATION: 'Integration_SQL2017' + SQL2019_WIN2019: + JOB_VMIMAGE: 'windows-2019' + TEST_CONFIGURATION: 'Integration_SQL2019' + SQL2019_WIN2022: + JOB_VMIMAGE: 'windows-2022' + TEST_CONFIGURATION: 'Integration_SQL2019' + SQL2022_WIN2019: + JOB_VMIMAGE: 'windows-2019' + TEST_CONFIGURATION: 'Integration_SQL2022' + SQL2022_WIN2022: + JOB_VMIMAGE: 'windows-2022' + TEST_CONFIGURATION: 'Integration_SQL2022' + pool: + vmImage: $(JOB_VMIMAGE) + timeoutInMinutes: 0 + steps: + - task: DownloadPipelineArtifact@2 + displayName: 'Download Build Artifact' + inputs: + buildType: 'current' + artifactName: $(buildArtifactName) + targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' + - task: PowerShell@2 + name: configureWinRM + displayName: 'Configure WinRM' + inputs: + targetType: 'inline' + script: 'winrm quickconfig -quiet' + pwsh: false + - powershell: | + Import-Module -Name ./tests/TestHelpers/CommonTestHelper.psm1 + Remove-PowerShellModuleFromCI -Name @('SqlServer', 'SQLPS') + Remove-Module -Name CommonTestHelper + name: cleanCIWorker + displayName: 'Clean CI worker' + - powershell: | + ./build.ps1 -Tasks test -CodeCoverageThreshold 0 -PesterTag $(TEST_CONFIGURATION) -PesterPath @( + # Run the integration tests in a specific group order. + # Group 0 + 'tests/Integration/Commands/Prerequisites.Integration.Tests.ps1' + # Group 1 + 'tests/Integration/Commands/Install-SqlDscReportingService.Integration.Tests.ps1' + # Group 8 + 'tests/Integration/Commands/Repair-SqlDscReportingService.Integration.Tests.ps1' + # Group 9 + 'tests/Integration/Commands/Uninstall-SqlDscReportingService.Integration.Tests.ps1' + ) + name: test + displayName: 'Run Integration Test' + - task: PublishTestResults@2 + displayName: 'Publish Test Results' + condition: succeededOrFailed() + inputs: + testResultsFormat: 'NUnit' + testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' + testRunTitle: 'Integration Commands ($(TEST_CONFIGURATION) / $(JOB_VMIMAGE))' + + - stage: Integration_Test_Commands_BIReportServer + displayName: 'Integration Test Commands - BI Report Server' + dependsOn: Integration_Test_Commands_SqlServer + jobs: + - job: Test_Integration + displayName: 'Commands' + strategy: + matrix: + SQL2022_WIN2019: + JOB_VMIMAGE: 'windows-2019' + TEST_CONFIGURATION: 'Integration_PowerBI' + SQL2022_WIN2022: + JOB_VMIMAGE: 'windows-2022' + TEST_CONFIGURATION: 'Integration_PowerBI' + pool: + vmImage: $(JOB_VMIMAGE) + timeoutInMinutes: 0 + steps: + - task: DownloadPipelineArtifact@2 + displayName: 'Download Build Artifact' + inputs: + buildType: 'current' + artifactName: $(buildArtifactName) + targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' + - task: PowerShell@2 + name: configureWinRM + displayName: 'Configure WinRM' + inputs: + targetType: 'inline' + script: 'winrm quickconfig -quiet' + pwsh: false + - powershell: | + Import-Module -Name ./tests/TestHelpers/CommonTestHelper.psm1 + Remove-PowerShellModuleFromCI -Name @('SqlServer', 'SQLPS') + Remove-Module -Name CommonTestHelper + name: cleanCIWorker + displayName: 'Clean CI worker' + - powershell: | + ./build.ps1 -Tasks test -CodeCoverageThreshold 0 -PesterTag $(TEST_CONFIGURATION) -PesterPath @( + # Run the integration tests in a specific group order. + # Group 0 + 'tests/Integration/Commands/Prerequisites.Integration.Tests.ps1' + # Group 1 + 'tests/Integration/Commands/Install-SqlDscBIReportServer.Integration.Tests.ps1' + # Group 8 + 'tests/Integration/Commands/Repair-SqlDscBIReportServer.Integration.Tests.ps1' + # Group 9 + 'tests/Integration/Commands/Uninstall-SqlDscBIReportServer.Integration.Tests.ps1' + ) + name: test + displayName: 'Run Integration Test' + - task: PublishTestResults@2 + displayName: 'Publish Test Results' + condition: succeededOrFailed() + inputs: + testResultsFormat: 'NUnit' + testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' + testRunTitle: 'Integration Commands ($(TEST_CONFIGURATION) / $(JOB_VMIMAGE))' + + - stage: Integration_Test_Resources_SqlServer + displayName: 'Integration Test Resources - SQL Server' + dependsOn: Quality_Test_and_Unit_Test jobs: - job: Test_Integration displayName: 'Integration' @@ -371,9 +499,12 @@ stages: testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' testRunTitle: 'Integration Resources ($(TEST_CONFIGURATION) / $(JOB_VMIMAGE))' - - job: Test_Integration_dbatools - displayName: 'Integration (dbatools)' - dependsOn: Test_Integration + - stage: Integration_Test_Resources_SqlServer_dbatools + displayName: 'Integration Test Resources - SQL Server (dbatools)' + dependsOn: Integration_Test_Resources_SqlServer + jobs: + - job: Test_Integration + displayName: 'Integration' strategy: matrix: SQL2016_WIN2022: @@ -461,8 +592,12 @@ stages: testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' testRunTitle: 'Integration (dbatools) ($(TEST_CONFIGURATION) / $(JOB_VMIMAGE))' - - job: Test_Integration_RS - displayName: 'Integration Reporting Services' + - stage: Integration_Test_Resources_ReportingServices + displayName: 'Integration Test Resources - Reporting Services' + dependsOn: Integration_Test_Resources_SqlServer + jobs: + - job: Test_Integration + displayName: 'Integration' strategy: matrix: SQL2016_WIN2019: @@ -537,9 +672,12 @@ stages: testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' testRunTitle: 'Integration RS ($(TEST_CONFIGURATION) / $(JOB_VMIMAGE))' - - job: Test_Integration_RS_dbatools - displayName: 'Integration Reporting Services (dbatools)' - dependsOn: Test_Integration_RS + - stage: Integration_Test_Resources_ReportingServices_dbatools + displayName: 'Integration Test Resources - Reporting Services (dbatools)' + dependsOn: Integration_Test_Resources_SqlServer + jobs: + - job: Test_Integration + displayName: 'Integration' strategy: matrix: SQL2016_WIN2022: @@ -599,8 +737,13 @@ stages: - stage: Deploy dependsOn: - Quality_Test_and_Unit_Test - - Integration_Test_Commands - - Integration_Test_Resources + - Integration_Test_Commands_SqlServer + - Integration_Test_Commands_ReportingServices + - Integration_Test_Commands_BIReportServer + - Integration_Test_Resources_SqlServer + - Integration_Test_Resources_SqlServer_dbatools + - Integration_Test_Resources_ReportingServices + - Integration_Test_Resources_ReportingServices_dbatools condition: | and( succeeded(), diff --git a/source/Private/Invoke-ReportServerSetupAction.ps1 b/source/Private/Invoke-ReportServerSetupAction.ps1 index ae9ac57265..678fe1c359 100644 --- a/source/Private/Invoke-ReportServerSetupAction.ps1 +++ b/source/Private/Invoke-ReportServerSetupAction.ps1 @@ -147,7 +147,7 @@ function Invoke-ReportServerSetupAction [Parameter(ParameterSetName = 'Install')] [Parameter(ParameterSetName = 'Repair')] - [ValidateSet('Development', 'Evaluation', 'ExpressAdvanced')] + [ValidateSet('Developer', 'Evaluation', 'ExpressAdvanced')] [System.String] $Edition, @@ -213,6 +213,9 @@ function Invoke-ReportServerSetupAction Assert-BoundParameter @assertBoundParameters + # Sensitive values. + $sensitiveValue = @() + # Default action is install or upgrade. $setupArgument = '/quiet /IAcceptLicenseTerms' @@ -228,6 +231,10 @@ function Invoke-ReportServerSetupAction if ($ProductKey) { $setupArgument += ' /PID={0}' -f $ProductKey + + $sensitiveValue += @( + $ProductKey + ) } if ($EditionUpgrade.IsPresent) @@ -237,7 +244,13 @@ function Invoke-ReportServerSetupAction if ($Edition) { - $setupArgument += ' /Edition={0}' -f $Edition + $editionMap = @{ + Developer = 'Dev' + Evaluation = 'Eval' + ExpressAdvanced = 'ExprAdv' + } + + $setupArgument += ' /Edition={0}' -f $editionMap.$Edition } if ($LogPath) @@ -257,11 +270,6 @@ function Invoke-ReportServerSetupAction $verboseSetupArgument = $setupArgument - # Sensitive values. - $sensitiveValue = @( - $ProductKey - ) - # Obfuscate sensitive values. foreach ($currentSensitiveValue in $sensitiveValue) { diff --git a/source/Public/Install-SqlDscBIReportServer.ps1 b/source/Public/Install-SqlDscBIReportServer.ps1 new file mode 100644 index 0000000000..123d75df08 --- /dev/null +++ b/source/Public/Install-SqlDscBIReportServer.ps1 @@ -0,0 +1,125 @@ +<# + .SYNOPSIS + Installs SQL Server Power BI Report Server. + + .DESCRIPTION + Installs SQL Server Power BI Report Server using the provided setup executable. + + .PARAMETER AcceptLicensingTerms + Required parameter to be able to run unattended install. By specifying this + parameter you acknowledge the acceptance of all license terms and notices for + the specified features, the terms and notices that the setup executable + normally asks for. + + .PARAMETER MediaPath + Specifies the path where to find the SQL Server installation media. On this + path the SQL Server setup executable must be found. + + .PARAMETER ProductKey + Specifies the product key to use for the installation, e.g. '12345-12345-12345-12345-12345'. + This parameter is mutually exclusive with the parameter Edition. + + .PARAMETER EditionUpgrade + Upgrades the edition of the installed product. Requires that either the + ProductKey or the Edition parameter is also assigned. By default no edition + upgrade is performed. + + .PARAMETER Edition + Specifies a free custom edition to use for the installation. This parameter + is mutually exclusive with the parameter ProductKey. + + .PARAMETER LogPath + Specifies the file path where to write the log files, e.g. 'C:\Logs\Install.log'. + By default log files are created under %TEMP%. + + .PARAMETER InstallFolder + Specifies the folder where to install the product, e.g. 'C:\Program Files\Power BI Report Server'. + By default the product is installed under the default installation folder. + + Reporting Services: %ProgramFiles%\Microsoft SQL Server Reporting Services + PI Report Server: %ProgramFiles%\Microsoft Power BI Report Server + + .PARAMETER SuppressRestart + Suppresses the restart of the computer after the installation is finished. + By default the computer is restarted after the installation is finished. + + .PARAMETER Timeout + Specifies how long to wait for the setup process to finish. Default value + is `7200` seconds (2 hours). If the setup process does not finish before + this time, an exception will be thrown. + + .PARAMETER Force + If specified the command will not ask for confirmation. Same as if Confirm:$false + is used. + + .EXAMPLE + Install-SqlDscBIReportServer -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' + + Installs Power BI Report Server with default settings. + + .EXAMPLE + Install-SqlDscBIReportServer -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' -ProductKey '12345-12345-12345-12345-12345' + + Installs Power BI Report Server using a product key. + + .EXAMPLE + Install-SqlDscBIReportServer -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' -Edition 'Evaluation' -InstallFolder 'C:\Program Files\Power BI Report Server' + + Installs Power BI Report Server in evaluation edition to a custom folder. + + .EXAMPLE + Install-SqlDscBIReportServer -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' -ProductKey '12345-12345-12345-12345-12345' -EditionUpgrade -LogPath 'C:\Logs\PowerBIReportServer_Install.log' + + Installs Power BI Report Server and upgrades the edition using a product key. Also specifies a custom log path. +#> +function Install-SqlDscBIReportServer +{ + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Because ShouldProcess is used in Invoke-SetupAction')] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] + [OutputType()] + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.SwitchParameter] + $AcceptLicensingTerms, + + [Parameter(Mandatory = $true)] + [System.String] + $MediaPath, + + [Parameter()] + [System.String] + $ProductKey, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $EditionUpgrade, + + [Parameter()] + [ValidateSet('Developer', 'Evaluation', 'ExpressAdvanced')] + [System.String] + $Edition, + + [Parameter()] + [System.String] + $LogPath, + + [Parameter()] + [System.String] + $InstallFolder, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SuppressRestart, + + [Parameter()] + [System.UInt32] + $Timeout = 7200, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Force + ) + + Invoke-ReportServerSetupAction -Install @PSBoundParameters +} diff --git a/source/Public/Install-SqlDscReportingService.ps1 b/source/Public/Install-SqlDscReportingService.ps1 new file mode 100644 index 0000000000..08482f83f0 --- /dev/null +++ b/source/Public/Install-SqlDscReportingService.ps1 @@ -0,0 +1,127 @@ +<# + .SYNOPSIS + Installs SQL Server Reporting Services or Power BI Report Server. + + .DESCRIPTION + Installs SQL Server Reporting Services or Power BI Report Server using + the provided setup executable. + + .PARAMETER AcceptLicensingTerms + Required parameter to be able to run unattended install. By specifying this + parameter you acknowledge the acceptance of all license terms and notices for + the specified features, the terms and notices that the setup executable + normally asks for. + + .PARAMETER MediaPath + Specifies the path where to find the SQL Server installation media. On this + path the SQL Server setup executable must be found. + + .PARAMETER ProductKey + Specifies the product key to use for the installation, e.g. '12345-12345-12345-12345-12345'. + This parameter is mutually exclusive with the parameter Edition. + + .PARAMETER EditionUpgrade + Upgrades the edition of the installed product. Requires that either the + ProductKey or the Edition parameter is also assigned. By default no edition + upgrade is performed. + + .PARAMETER Edition + Specifies a free custom edition to use for the installation. This parameter + is mutually exclusive with the parameter ProductKey. + + .PARAMETER LogPath + Specifies the file path where to write the log files, e.g. 'C:\Logs\Install.log'. + By default log files are created under %TEMP%. + + .PARAMETER InstallFolder + Specifies the folder where to install the product, e.g. 'C:\Program Files\SSRS'. + By default the product is installed under the default installation folder. + + Reporting Services: %ProgramFiles%\Microsoft SQL Server Reporting Services + PI Report Server: %ProgramFiles%\Microsoft Power BI Report Server + + .PARAMETER SuppressRestart + Suppresses the restart of the computer after the installation is finished. + By default the computer is restarted after the installation is finished. + + .PARAMETER Timeout + Specifies how long to wait for the setup process to finish. Default value + is `7200` seconds (2 hours). If the setup process does not finish before + this time, an exception will be thrown. + + .PARAMETER Force + If specified the command will not ask for confirmation. Same as if Confirm:$false + is used. + + .EXAMPLE + Install-SqlDscReportingService -AcceptLicensingTerms -MediaPath 'E:\SQLServerReportingServices.exe' + + Installs SQL Server Reporting Services with default settings. + + .EXAMPLE + Install-SqlDscReportingService -AcceptLicensingTerms -MediaPath 'E:\SQLServerReportingServices.exe' -ProductKey '12345-12345-12345-12345-12345' + + Installs SQL Server Reporting Services using a product key. + + .EXAMPLE + Install-SqlDscReportingService -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' -Edition 'Evaluation' -InstallFolder 'C:\Program Files\Power BI Report Server' + + Installs Power BI Report Server in evaluation edition to a custom folder. + + .EXAMPLE + Install-SqlDscReportingService -AcceptLicensingTerms -MediaPath 'E:\SQLServerReportingServices.exe' -ProductKey '12345-12345-12345-12345-12345' -EditionUpgrade -LogPath 'C:\Logs\SSRS_Install.log' + + Installs SQL Server Reporting Services and upgrades the edition using a + product key. Also specifies a custom log path. +#> +function Install-SqlDscReportingService +{ + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Because ShouldProcess is used in Invoke-SetupAction')] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] + [OutputType()] + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.SwitchParameter] + $AcceptLicensingTerms, + + [Parameter(Mandatory = $true)] + [System.String] + $MediaPath, + + [Parameter()] + [System.String] + $ProductKey, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $EditionUpgrade, + + [Parameter()] + [ValidateSet('Developer', 'Evaluation', 'ExpressAdvanced')] + [System.String] + $Edition, + + [Parameter()] + [System.String] + $LogPath, + + [Parameter()] + [System.String] + $InstallFolder, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SuppressRestart, + + [Parameter()] + [System.UInt32] + $Timeout = 7200, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Force + ) + + Invoke-ReportServerSetupAction -Install @PSBoundParameters +} diff --git a/source/Public/Repair-SqlDscBIReportServer.ps1 b/source/Public/Repair-SqlDscBIReportServer.ps1 new file mode 100644 index 0000000000..acf41765cd --- /dev/null +++ b/source/Public/Repair-SqlDscBIReportServer.ps1 @@ -0,0 +1,121 @@ +<# + .SYNOPSIS + Repairs an existing SQL Server Power BI Report Server installation. + + .DESCRIPTION + Repairs an existing SQL Server Power BI Report Server installation using + the provided setup executable. + + .PARAMETER AcceptLicensingTerms + Required parameter to be able to run unattended repair. By specifying this + parameter you acknowledge the acceptance of all license terms and notices for + the specified features, the terms and notices that the setup executable + normally asks for. + + .PARAMETER MediaPath + Specifies the path where to find the SQL Server installation media. On this + path the SQL Server setup executable must be found. + + .PARAMETER ProductKey + Specifies the product key to use for the repair, e.g. '12345-12345-12345-12345-12345'. + This parameter is mutually exclusive with the parameter Edition. + + .PARAMETER EditionUpgrade + Upgrades the edition of the installed product. Requires that either the + ProductKey or the Edition parameter is also assigned. By default no edition + upgrade is performed. + + .PARAMETER Edition + Specifies a free custom edition to use for the repair. This parameter + is mutually exclusive with the parameter ProductKey. + + .PARAMETER LogPath + Specifies the file path where to write the log files, e.g. 'C:\Logs\Repair.log'. + By default log files are created under %TEMP%. + + .PARAMETER InstallFolder + Specifies the folder where to install the product, e.g. 'C:\Program Files\Power BI Report Server'. + By default the product is installed under the default installation folder. + + PI Report Server: %ProgramFiles%\Microsoft Power BI Report Server + + .PARAMETER SuppressRestart + Suppresses the restart of the computer after the repair is finished. + By default the computer is restarted after the repair is finished. + + .PARAMETER Timeout + Specifies how long to wait for the setup process to finish. Default value + is `7200` seconds (2 hours). If the setup process does not finish before + this time, an exception will be thrown. + + .PARAMETER Force + If specified the command will not ask for confirmation. Same as if Confirm:$false + is used. + + .EXAMPLE + Repair-SqlDscBIReportServer -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' + + Repairs Power BI Report Server with default settings. + + .EXAMPLE + Repair-SqlDscBIReportServer -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' -ProductKey '12345-12345-12345-12345-12345' -EditionUpgrade + + Repairs Power BI Report Server and upgrades the edition using a + product key. + + .EXAMPLE + Repair-SqlDscBIReportServer -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' -LogPath 'C:\Logs\PowerBIReportServer_Repair.log' + + Repairs Power BI Report Server and specifies a custom log path. +#> +function Repair-SqlDscBIReportServer +{ + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Because ShouldProcess is used in Invoke-SetupAction')] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] + [OutputType()] + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.SwitchParameter] + $AcceptLicensingTerms, + + [Parameter(Mandatory = $true)] + [System.String] + $MediaPath, + + [Parameter()] + [System.String] + $ProductKey, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $EditionUpgrade, + + [Parameter()] + [ValidateSet('Developer', 'Evaluation', 'ExpressAdvanced')] + [System.String] + $Edition, + + [Parameter()] + [System.String] + $LogPath, + + [Parameter()] + [System.String] + $InstallFolder, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SuppressRestart, + + [Parameter()] + [System.UInt32] + $Timeout = 7200, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Force + ) + + Invoke-ReportServerSetupAction -Repair @PSBoundParameters +} diff --git a/source/Public/Repair-SqlDscReportingService.ps1 b/source/Public/Repair-SqlDscReportingService.ps1 new file mode 100644 index 0000000000..2c03dd2733 --- /dev/null +++ b/source/Public/Repair-SqlDscReportingService.ps1 @@ -0,0 +1,123 @@ +<# + .SYNOPSIS + Repairs an existing SQL Server Reporting Services or Power BI Report Server + installation. + + .DESCRIPTION + Repairs an existing SQL Server Reporting Services or Power BI Report Server + installation using the provided setup executable. + + .PARAMETER AcceptLicensingTerms + Required parameter to be able to run unattended repair. By specifying this + parameter you acknowledge the acceptance of all license terms and notices for + the specified features, the terms and notices that the setup executable + normally asks for. + + .PARAMETER MediaPath + Specifies the path where to find the SQL Server installation media. On this + path the SQL Server setup executable must be found. + + .PARAMETER ProductKey + Specifies the product key to use for the repair, e.g. '12345-12345-12345-12345-12345'. + This parameter is mutually exclusive with the parameter Edition. + + .PARAMETER EditionUpgrade + Upgrades the edition of the installed product. Requires that either the + ProductKey or the Edition parameter is also assigned. By default no edition + upgrade is performed. + + .PARAMETER Edition + Specifies a free custom edition to use for the repair. This parameter + is mutually exclusive with the parameter ProductKey. + + .PARAMETER LogPath + Specifies the file path where to write the log files, e.g. 'C:\Logs\Repair.log'. + By default log files are created under %TEMP%. + + .PARAMETER InstallFolder + Specifies the folder where to install the product, e.g. 'C:\Program Files\SSRS'. + By default the product is installed under the default installation folder. + + Reporting Services: %ProgramFiles%\Microsoft SQL Server Reporting Services + PI Report Server: %ProgramFiles%\Microsoft Power BI Report Server + + .PARAMETER SuppressRestart + Suppresses the restart of the computer after the repair is finished. + By default the computer is restarted after the repair is finished. + + .PARAMETER Timeout + Specifies how long to wait for the setup process to finish. Default value + is `7200` seconds (2 hours). If the setup process does not finish before + this time, an exception will be thrown. + + .PARAMETER Force + If specified the command will not ask for confirmation. Same as if Confirm:$false + is used. + + .EXAMPLE + Repair-SqlDscReportingService -AcceptLicensingTerms -MediaPath 'E:\SQLServerReportingServices.exe' + + Repairs SQL Server Reporting Services with default settings. + + .EXAMPLE + Repair-SqlDscReportingService -AcceptLicensingTerms -MediaPath 'E:\SQLServerReportingServices.exe' -ProductKey '12345-12345-12345-12345-12345' -EditionUpgrade + + Repairs SQL Server Reporting Services and upgrades the edition using a + product key. + + .EXAMPLE + Repair-SqlDscReportingService -AcceptLicensingTerms -MediaPath 'E:\PowerBIReportServer.exe' -LogPath 'C:\Logs\PowerBIReportServer_Repair.log' + + Repairs Power BI Report Server and specifies a custom log path. +#> +function Repair-SqlDscReportingService +{ + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Because ShouldProcess is used in Invoke-SetupAction')] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] + [OutputType()] + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.SwitchParameter] + $AcceptLicensingTerms, + + [Parameter(Mandatory = $true)] + [System.String] + $MediaPath, + + [Parameter()] + [System.String] + $ProductKey, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $EditionUpgrade, + + [Parameter()] + [ValidateSet('Developer', 'Evaluation', 'ExpressAdvanced')] + [System.String] + $Edition, + + [Parameter()] + [System.String] + $LogPath, + + [Parameter()] + [System.String] + $InstallFolder, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SuppressRestart, + + [Parameter()] + [System.UInt32] + $Timeout = 7200, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Force + ) + + Invoke-ReportServerSetupAction -Repair @PSBoundParameters +} diff --git a/source/Public/Save-SqlDscSqlServerMediaFile.ps1 b/source/Public/Save-SqlDscSqlServerMediaFile.ps1 index 07ad5d734b..8db9dcda58 100644 --- a/source/Public/Save-SqlDscSqlServerMediaFile.ps1 +++ b/source/Public/Save-SqlDscSqlServerMediaFile.ps1 @@ -34,11 +34,21 @@ Forces the download of the media file even if the file already exists at the specified destination path. + .PARAMETER SkipExecution + When specified, and the URL points to an executable (.exe), the function will + download the executable file without executing it. The file will be saved using + the provided FileName parameter. + .EXAMPLE Save-SqlDscSqlServerMediaFile -Url 'https://download.microsoft.com/download/c/c/9/cc9c6797-383c-4b24-8920-dc057c1de9d3/SQL2022-SSEI-Dev.exe' -DestinationPath 'C:\path\to\destination' This downloads the SQL Server 2022 media and saves it to the specified destination path. + .EXAMPLE + Save-SqlDscSqlServerMediaFile -Url 'https://download.microsoft.com/download/c/c/9/cc9c6797-383c-4b24-8920-dc057c1de9d3/SQL2022-SSEI-Dev.exe' -DestinationPath 'C:\path\to\destination' -SkipExecution + + This downloads the SQL Server 2022 installer executable but does not execute it to extract the ISO. + .EXAMPLE Save-SqlDscSqlServerMediaFile -Url 'https://download.microsoft.com/download/d/a/2/da259851-b941-459d-989c-54a18a5d44dd/SQL2019-SSEI-Dev.exe' -DestinationPath 'C:\path\to\destination' @@ -85,7 +95,11 @@ function Save-SqlDscSqlServerMediaFile [Parameter()] [System.Management.Automation.SwitchParameter] - $Force + $Force, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SkipExecution ) if ($Force.IsPresent -and -not $Confirm) @@ -93,7 +107,7 @@ function Save-SqlDscSqlServerMediaFile $ConfirmPreference = 'None' } - if ((Get-Item -Path "$DestinationPath/*.iso" -Force).Count -gt 0) + if ((Get-Item -Path "$DestinationPath/*.iso" -Force).Count -gt 0 -and -not $SkipExecution) { $auditAlreadyPresentMessage = $script:localizedData.SqlServerMediaFile_Save_InvalidDestinationFolder @@ -165,7 +179,7 @@ function Save-SqlDscSqlServerMediaFile $ProgressPreference = $previousProgressPreference } - if ($isExecutable) + if ($isExecutable -and -not $SkipExecution) { Write-Verbose -Message $script:localizedData.SqlServerMediaFile_Save_IsExecutable diff --git a/source/Public/Uninstall-SqlDscBIReportServer.ps1 b/source/Public/Uninstall-SqlDscBIReportServer.ps1 new file mode 100644 index 0000000000..75917c55f9 --- /dev/null +++ b/source/Public/Uninstall-SqlDscBIReportServer.ps1 @@ -0,0 +1,73 @@ +<# + .SYNOPSIS + Uninstalls SQL Server Power BI Report Server. + + .DESCRIPTION + Uninstalls SQL Server Power BI Report Server using the provided setup executable. + + .PARAMETER MediaPath + Specifies the path where to find the SQL Server installation media. On this + path the SQL Server setup executable must be found. + + .PARAMETER LogPath + Specifies the file path where to write the log files, e.g. 'C:\Logs\Uninstall.log'. + By default log files are created under %TEMP%. + + .PARAMETER SuppressRestart + Suppresses the restart of the computer after the uninstallation is finished. + By default the computer is restarted after the uninstallation is finished. + + .PARAMETER Timeout + Specifies how long to wait for the setup process to finish. Default value + is `7200` seconds (2 hours). If the setup process does not finish before + this time, an exception will be thrown. + + .PARAMETER Force + If specified the command will not ask for confirmation. Same as if Confirm:$false + is used. + + .EXAMPLE + Uninstall-SqlDscBIReportServer -MediaPath 'E:\PowerBIReportServer.exe' + + Uninstalls Power BI Report Server. + + .EXAMPLE + Uninstall-SqlDscBIReportServer -MediaPath 'E:\PowerBIReportServer.exe' -LogPath 'C:\Logs\PowerBIReportServer_Uninstall.log' + + Uninstalls Power BI Report Server and specifies a custom log path. + + .EXAMPLE + Uninstall-SqlDscBIReportServer -MediaPath 'E:\PowerBIReportServer.exe' -Force + + Uninstalls Power BI Report Server without prompting for confirmation. +#> +function Uninstall-SqlDscBIReportServer +{ + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Because ShouldProcess is used in Invoke-SetupAction')] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] + [OutputType()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $MediaPath, + + [Parameter()] + [System.String] + $LogPath, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SuppressRestart, + + [Parameter()] + [System.UInt32] + $Timeout = 7200, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Force + ) + + Invoke-ReportServerSetupAction -Uninstall @PSBoundParameters +} diff --git a/source/Public/Uninstall-SqlDscReportingService.ps1 b/source/Public/Uninstall-SqlDscReportingService.ps1 new file mode 100644 index 0000000000..7178c4f437 --- /dev/null +++ b/source/Public/Uninstall-SqlDscReportingService.ps1 @@ -0,0 +1,74 @@ +<# + .SYNOPSIS + Uninstalls SQL Server Reporting Services or Power BI Report Server. + + .DESCRIPTION + Uninstalls SQL Server Reporting Services or Power BI Report Server using + the provided setup executable. + + .PARAMETER MediaPath + Specifies the path where to find the SQL Server installation media. On this + path the SQL Server setup executable must be found. + + .PARAMETER LogPath + Specifies the file path where to write the log files, e.g. 'C:\Logs\Uninstall.log'. + By default log files are created under %TEMP%. + + .PARAMETER SuppressRestart + Suppresses the restart of the computer after the uninstallation is finished. + By default the computer is restarted after the uninstallation is finished. + + .PARAMETER Timeout + Specifies how long to wait for the setup process to finish. Default value + is `7200` seconds (2 hours). If the setup process does not finish before + this time, an exception will be thrown. + + .PARAMETER Force + If specified the command will not ask for confirmation. Same as if Confirm:$false + is used. + + .EXAMPLE + Uninstall-SqlDscReportingService -MediaPath 'E:\SQLServerReportingServices.exe' + + Uninstalls SQL Server Reporting Services. + + .EXAMPLE + Uninstall-SqlDscReportingService -MediaPath 'E:\PowerBIReportServer.exe' -LogPath 'C:\Logs\PowerBIReportServer_Uninstall.log' + + Uninstalls Power BI Report Server and specifies a custom log path. + + .EXAMPLE + Uninstall-SqlDscReportingService -MediaPath 'E:\SQLServerReportingServices.exe' -Force + + Uninstalls SQL Server Reporting Services without prompting for confirmation. +#> +function Uninstall-SqlDscReportingService +{ + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Because ShouldProcess is used in Invoke-SetupAction')] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] + [OutputType()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $MediaPath, + + [Parameter()] + [System.String] + $LogPath, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SuppressRestart, + + [Parameter()] + [System.UInt32] + $Timeout = 7200, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Force + ) + + Invoke-ReportServerSetupAction -Uninstall @PSBoundParameters +} diff --git a/tests/Integration/Commands/Install-SqlDscBIReportServer.Integration.Tests.ps1 b/tests/Integration/Commands/Install-SqlDscBIReportServer.Integration.Tests.ps1 new file mode 100644 index 0000000000..5f6ff0bde9 --- /dev/null +++ b/tests/Integration/Commands/Install-SqlDscBIReportServer.Integration.Tests.ps1 @@ -0,0 +1,71 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +Describe 'Install-SqlDscBIReportServer' -Tag @('Integration_PowerBI') { + BeforeAll { + Write-Verbose -Message ('Running integration test as user ''{0}''.' -f $env:UserName) -Verbose + + $script:temporaryFolder = Get-TemporaryFolder + + # Get the path to the Power BI Report Server executable + $powerBIReportServerExecutable = Join-Path -Path $script:temporaryFolder -ChildPath 'PowerBIReportServer.exe' + } + + Context 'When installing Power BI Report Server' { + It 'Should run the command without throwing' { + { + # Set splatting parameters for Install-SqlDscBIReportServer + $installSqlDscBIReportServerParameters = @{ + AcceptLicensingTerms = $true + MediaPath = $powerBIReportServerExecutable + Edition = 'Evaluation' + LogPath = Join-Path -Path $script:temporaryFolder -ChildPath 'PowerBIReportServer_Install.log' + SuppressRestart = $true + Verbose = $true + Force = $true + } + + Install-SqlDscBIReportServer @installSqlDscBIReportServerParameters -ErrorAction 'Stop' + } | Should -Not -Throw + } + + It 'Should have installed Power BI Report Server' { + # Validate the Power BI Report Server installation + $reportServerService = Get-Service -Name 'PowerBIReportServer' + + $reportServerService | Should -Not -BeNullOrEmpty + $reportServerService.Status | Should -Be 'Running' + } + + It 'Should stop the Power BI Report Server service' { + # Stop the Power BI Report Server service to save memory on the build worker + $stopServiceResult = Stop-Service -Name 'PowerBIReportServer' -Force -PassThru -Verbose -ErrorAction 'Stop' + + write-verbose -Message ($stopServiceResult | Out-String) -Verbose + + $stopServiceResult.Status | Should -Be 'Stopped' + } + } +} diff --git a/tests/Integration/Commands/Install-SqlDscReportingService.Integration.Tests.ps1 b/tests/Integration/Commands/Install-SqlDscReportingService.Integration.Tests.ps1 new file mode 100644 index 0000000000..ac20a8803f --- /dev/null +++ b/tests/Integration/Commands/Install-SqlDscReportingService.Integration.Tests.ps1 @@ -0,0 +1,71 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +Describe 'Install-SqlDscReportingService' -Tag @('Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + BeforeAll { + Write-Verbose -Message ('Running integration test as user ''{0}''.' -f $env:UserName) -Verbose + + $script:temporaryFolder = Get-TemporaryFolder + + # Get the path to the Reporting Services executable + $reportingServicesExecutable = Join-Path -Path $script:temporaryFolder -ChildPath 'SQLServerReportingServices.exe' + } + + Context 'When installing Reporting Services' { + It 'Should run the command without throwing' { + { + # Set splatting parameters for Install-SqlDscReportingService + $installSqlDscReportingServicesParameters = @{ + AcceptLicensingTerms = $true + MediaPath = $reportingServicesExecutable + Edition = 'Developer' + LogPath = Join-Path -Path $script:temporaryFolder -ChildPath 'SSRS_Install.log' + SuppressRestart = $true + Verbose = $true + Force = $true + } + + Install-SqlDscReportingService @installSqlDscReportingServicesParameters -ErrorAction 'Stop' + } | Should -Not -Throw + } + + It 'Should have installed Reporting Services' { + # Validate the Reporting Services installation + $reportServerService = Get-Service -Name 'SQLServerReportingServices' + + $reportServerService | Should -Not -BeNullOrEmpty + $reportServerService.Status | Should -Be 'Running' + } + + It 'Should stop the Reporting Services service' { + # Stop the Reporting Services service to save memory on the build worker + $stopServiceResult = Stop-Service -Name 'SQLServerReportingServices' -Force -PassThru -Verbose -ErrorAction 'Stop' + + write-verbose -Message ($stopServiceResult | Out-String) -Verbose + + $stopServiceResult.Status | Should -Be 'Stopped' + } + } +} diff --git a/tests/Integration/Commands/Prerequisites.Integration.Tests.ps1 b/tests/Integration/Commands/Prerequisites.Integration.Tests.ps1 index 9bae6bbbe7..a60893f052 100644 --- a/tests/Integration/Commands/Prerequisites.Integration.Tests.ps1 +++ b/tests/Integration/Commands/Prerequisites.Integration.Tests.ps1 @@ -25,7 +25,7 @@ BeforeDiscovery { # CSpell: ignore Remoting Describe 'Prerequisites' { - Context 'Create required local Windows users' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + Context 'Create required local Windows users' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022', 'Integration_PowerBI') { BeforeAll { $password = ConvertTo-SecureString -String 'P@ssw0rd1' -AsPlainText -Force } @@ -45,7 +45,7 @@ Describe 'Prerequisites' { } } - Context 'Should create required local Windows service accounts' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + Context 'Should create required local Windows service accounts' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022', 'Integration_PowerBI') { BeforeAll { $password = ConvertTo-SecureString -String 'yig-C^Equ3' -AsPlainText -Force } @@ -79,7 +79,7 @@ Describe 'Prerequisites' { } } - Context 'Add local Windows users to local groups' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + Context 'Add local Windows users to local groups' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022', 'Integration_PowerBI') { It 'Should add SqlInstall to local administrator group' { # Add user to local administrator group Add-LocalGroupMember -Group 'Administrators' -Member 'SqlInstall' @@ -116,7 +116,7 @@ Describe 'Prerequisites' { $mediaFile.Name | Should -Be 'media.iso' } - It 'Should download SQL Server 2022 media' -Tag @('Integration_SQL2022') { + It 'Should download SQL Server 2022 media' -Tag @('Integration_SQL2022', 'Integration_PowerBI') { $url = 'https://download.microsoft.com/download/c/c/9/cc9c6797-383c-4b24-8920-dc057c1de9d3/SQL2022-SSEI-Dev.exe' $script:mediaFile = Save-SqlDscSqlServerMediaFile -Url $url -DestinationPath $env:TEMP -Force -Quiet -ErrorAction 'Stop' @@ -125,7 +125,7 @@ Describe 'Prerequisites' { } } - Context 'Mount SQL Server media' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + Context 'Mount SQL Server media' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022', 'Integration_PowerBI') { It 'Should mount the media to a drive letter' { $mountedImage = Mount-DiskImage -ImagePath $script:mediaFile $mountedImage | Should -BeOfType 'Microsoft.Management.Infrastructure.CimInstance' @@ -150,14 +150,14 @@ Describe 'Prerequisites' { } Context 'Install correct version of module SqlServer' { - It 'Should have the minimum required version of Microsoft.PowerShell.PSResourceGet' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + It 'Should have the minimum required version of Microsoft.PowerShell.PSResourceGet' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022', 'Integration_PowerBI') { $module = Get-Module -Name 'Microsoft.PowerShell.PSResourceGet' -ListAvailable $module | Should -HaveCount 1 $module.Version -ge '1.0.4.1' | Should -BeTrue } - It 'Should have a resource repository PSGallery with correct URI' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + It 'Should have a resource repository PSGallery with correct URI' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022', 'Integration_PowerBI') { $resourceRepository = Get-PSResourceRepository -Name 'PSGallery' $resourceRepository | Should -HaveCount 1 @@ -179,7 +179,7 @@ Describe 'Prerequisites' { $module.Version -eq '21.1.18256' | Should -BeTrue } - It 'Should install SqlServer module version 22.2.0' -Tag @('Integration_SQL2022') { + It 'Should install SqlServer module version 22.2.0' -Tag @('Integration_SQL2022', 'Integration_PowerBI') { #Install-Module -Name 'SqlServer' -RequiredVersion '22.2.0' -Force -ErrorAction 'Stop' $module = Install-PSResource -Name 'SqlServer' -Version '22.2.0' -Scope 'AllUsers' -TrustRepository -ErrorAction 'Stop' -Confirm:$false -PassThru @@ -187,7 +187,7 @@ Describe 'Prerequisites' { $module.Version -eq '22.2.0' | Should -BeTrue } - It 'Should have SqlServer module version 22.2.0 available' -Tag @('Integration_SQL2022') { + It 'Should have SqlServer module version 22.2.0 available' -Tag @('Integration_SQL2022', 'Integration_PowerBI') { $module = Get-Module -Name 'SqlServer' -ListAvailable $module | Should -HaveCount 1 @@ -195,7 +195,7 @@ Describe 'Prerequisites' { } } - Context 'Test PS Remoting to localhost' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + Context 'Test PS Remoting to localhost' -Tag @('Integration_SQL2016', 'Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022', 'Integration_PowerBI') { It 'Should successfully run a command on localhost using PS Remoting' { # This is a simple test to verify that PS Remoting is working. # TODO: This fails on Appveyor, but works locally when debugging on AppVeyor. Investigate why. @@ -204,4 +204,54 @@ Describe 'Prerequisites' { $result | Should -Be 1 } } + + Context 'Download correct SQL Server 2017 Reporting Services installation executable' { + It 'Should download SQL Server 2017 Reporting Services installation executable' -Tag @('Integration_SQL2017') { + # Microsoft SQL Server Reporting Services (October 2017) + $url = 'https://download.microsoft.com/download/E/6/4/E6477A2A-9B58-40F7-8AD6-62BB8491EA78/SQLServerReportingServices.exe' + + # Put the executable in a temporary folder that can be accessed by other tests + $script:mediaFile = Save-SqlDscSqlServerMediaFile -SkipExecution -Url $url -FileName 'SQLServerReportingServices.exe' -DestinationPath (Get-TemporaryFolder) -Force -Quiet -ErrorAction 'Stop' + + $mediaFile.Name | Should -Be 'SQLServerReportingServices.exe' + } + } + + Context 'Download correct SQL Server 2019 Reporting Services installation executable' { + It 'Should download SQL Server 2019 Reporting Services installation executable' -Tag @('Integration_SQL2019') { + # Microsoft SQL Server 2019 Reporting Services (15.0.1102.1047 - 2/6/2023) + $url = 'https://download.microsoft.com/download/1/a/a/1aaa9177-3578-4931-b8f3-373b24f63342/SQLServerReportingServices.exe' + + # Put the executable in a temporary folder that can be accessed by other tests + $script:mediaFile = Save-SqlDscSqlServerMediaFile -SkipExecution -Url $url -FileName 'SQLServerReportingServices.exe' -DestinationPath (Get-TemporaryFolder) -Force -Quiet -ErrorAction 'Stop' + + $mediaFile.Name | Should -Be 'SQLServerReportingServices.exe' + } + } + + Context 'Download correct SQL Server 2022 Reporting Services installation executable' { + It 'Should download SQL Server 2022 Reporting Services installation executable' -Tag @('Integration_SQL2022') { + # Microsoft SQL Server 2022 Reporting Services (16.0.1113.11 - 11/23/2022) + $url = 'https://download.microsoft.com/download/8/3/2/832616ff-af64-42b5-a0b1-5eb07f71dec9/SQLServerReportingServices.exe' + + # Put the executable in a temporary folder that can be accessed by other tests + $script:mediaFile = Save-SqlDscSqlServerMediaFile -SkipExecution -Url $url -FileName 'SQLServerReportingServices.exe' -DestinationPath (Get-TemporaryFolder) -Force -Quiet -ErrorAction 'Stop' + + $mediaFile.Name | Should -Be 'SQLServerReportingServices.exe' + } + } + + Context 'Download correct Power BI Report Server installation executable' { + # This should always use the latest version of Power BI Report Server, and use the latest tag used in pipeline. + It 'Should download Power BI Report Server installation executable' -Tag @('Integration_PowerBI') { + # https://sqlserverbuilds.blogspot.com/2021/04/power-bi-report-server-versions.html + # 15.0.1117.98 - 2025-01-22 + $url = 'https://download.microsoft.com/download/2/7/3/2739a88a-4769-4700-8748-1a01ddf60974/PowerBIReportServer.exe' + + # Put the executable in a temporary folder that can be accessed by other tests + $script:mediaFile = Save-SqlDscSqlServerMediaFile -SkipExecution -Url $url -FileName 'PowerBIReportServer.exe' -DestinationPath (Get-TemporaryFolder) -Force -Quiet -ErrorAction 'Stop' + + $mediaFile.Name | Should -Be 'PowerBIReportServer.exe' + } + } } diff --git a/tests/Integration/Commands/Repair-SqlDscBIReportServer.Integration.Tests.ps1 b/tests/Integration/Commands/Repair-SqlDscBIReportServer.Integration.Tests.ps1 new file mode 100644 index 0000000000..f4f70828bf --- /dev/null +++ b/tests/Integration/Commands/Repair-SqlDscBIReportServer.Integration.Tests.ps1 @@ -0,0 +1,70 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +Describe 'Repair-SqlDscBIReportServer' -Tag @('Integration_PowerBI') { + BeforeAll { + Write-Verbose -Message ('Running integration test as user ''{0}''.' -f $env:UserName) -Verbose + + # Starting the Power BI Report Server service prior to running tests. + Start-Service -Name 'PowerBIReportServer' -Verbose -ErrorAction 'Stop' + + $script:temporaryFolder = Get-TemporaryFolder + + # Get the path to the Power BI Report Server executable + $powerBIReportServerExecutable = Join-Path -Path $script:temporaryFolder -ChildPath 'PowerBIReportServer.exe' + } + + It 'Should have the BI Report Server service running' { + $getServiceResult = Get-Service -Name 'PowerBIReportServer' -ErrorAction 'Stop' + + $getServiceResult.Status | Should -Be 'Running' + } + + Context 'When repairing BI Report Server' { + It 'Should run the command without throwing' { + { + # Set splatting parameters for Repair-SqlDscBIReportServer + $repairSqlDscBIReportServerParameters = @{ + AcceptLicensingTerms = $true + MediaPath = $powerBIReportServerExecutable + LogPath = Join-Path -Path $script:temporaryFolder -ChildPath 'SSRS_Repair.log' + SuppressRestart = $true + Verbose = $true + ErrorAction = 'Stop' + Force = $true + } + + Repair-SqlDscBIReportServer @repairSqlDscBIReportServerParameters + } | Should -Not -Throw + } + + It 'Should still have a Power BI Report Server service running after repair' { + $getServiceResult = Get-Service -Name 'PowerBIReportServer' -ErrorAction 'Stop' + + $getServiceResult | Should -Not -BeNullOrEmpty + $getServiceResult.Status | Should -Be 'Running' + } + } +} diff --git a/tests/Integration/Commands/Repair-SqlDscReportingService.Integration.Tests.ps1 b/tests/Integration/Commands/Repair-SqlDscReportingService.Integration.Tests.ps1 new file mode 100644 index 0000000000..f568a63a49 --- /dev/null +++ b/tests/Integration/Commands/Repair-SqlDscReportingService.Integration.Tests.ps1 @@ -0,0 +1,70 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +Describe 'Repair-SqlDscReportingService' -Tag @('Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + BeforeAll { + Write-Verbose -Message ('Running integration test as user ''{0}''.' -f $env:UserName) -Verbose + + # Starting the Power BI Report Server service prior to running tests. + Start-Service -Name 'SQLServerReportingServices' -Verbose -ErrorAction 'Stop' + + $script:temporaryFolder = Get-TemporaryFolder + + # Get the path to the Reporting Services executable + $reportingServicesExecutable = Join-Path -Path $script:temporaryFolder -ChildPath 'SQLServerReportingServices.exe' + } + + It 'Should have the Reporting Services service running' { + $getServiceResult = Get-Service -Name 'SQLServerReportingServices' -ErrorAction 'Stop' + + $getServiceResult.Status | Should -Be 'Running' + } + + Context 'When repairing Reporting Services' { + It 'Should run the repair command without throwing' { + { + # Set splatting parameters for Repair-SqlDscReportingService + $repairSqlDscReportingServiceParameters = @{ + AcceptLicensingTerms = $true + MediaPath = $reportingServicesExecutable + LogPath = Join-Path -Path $script:temporaryFolder -ChildPath 'SSRS_Repair.log' + SuppressRestart = $true + Verbose = $true + ErrorAction = 'Stop' + Force = $true + } + + Repair-SqlDscReportingService @repairSqlDscReportingServiceParameters + } | Should -Not -Throw + } + + It 'Should still have the SQL Server Reporting Services service running after repair' { + $getServiceResult = Get-Service -Name 'SQLServerReportingServices' -ErrorAction 'Stop' + + $getServiceResult | Should -Not -BeNullOrEmpty + $getServiceResult.Status | Should -Be 'Running' + } + } +} diff --git a/tests/Integration/Commands/Uninstall-SqlDscBIReportServer.Integration.Tests.ps1 b/tests/Integration/Commands/Uninstall-SqlDscBIReportServer.Integration.Tests.ps1 new file mode 100644 index 0000000000..bff9db701b --- /dev/null +++ b/tests/Integration/Commands/Uninstall-SqlDscBIReportServer.Integration.Tests.ps1 @@ -0,0 +1,66 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +Describe 'Uninstall-SqlDscBIReportServer' -Tag @('Integration_PowerBI') { + BeforeAll { + Write-Verbose -Message ('Running integration test as user ''{0}''.' -f $env:UserName) -Verbose + + # Starting the Power BI Report Server service prior to running tests. + Start-Service -Name 'PowerBIReportServer' -Verbose -ErrorAction 'Stop' + + $script:temporaryFolder = Get-TemporaryFolder + + # Get the path to the Power BI Report Server executable + $powerBIReportServerExecutable = Join-Path -Path $script:temporaryFolder -ChildPath 'PowerBIReportServer.exe' + } + + It 'Should have the BI Report Server service running' { + $getServiceResult = Get-Service -Name 'PowerBIReportServer' -ErrorAction 'Stop' + + $getServiceResult.Status | Should -Be 'Running' + } + + Context 'When uninstalling BI Report Server' { + It 'Should run the command without throwing' { + { + # Set splatting parameters for Uninstall-SqlDscBIReportServer + $uninstallSqlDscBIReportServerParameters = @{ + MediaPath = $powerBIReportServerExecutable + LogPath = Join-Path -Path $script:temporaryFolder -ChildPath 'SSRS_Uninstall.log' + SuppressRestart = $true + Verbose = $true + ErrorAction = 'Stop' + Force = $true + } + + Uninstall-SqlDscBIReportServer @uninstallSqlDscBIReportServerParameters + } | Should -Not -Throw + } + + It 'Should not have a Power BI Report Server service' { + Get-Service -Name 'PowerBIReportServer' -ErrorAction 'Ignore' | Should -BeNullOrEmpty + } + } +} diff --git a/tests/Integration/Commands/Uninstall-SqlDscReportingService.Integration.Tests.ps1 b/tests/Integration/Commands/Uninstall-SqlDscReportingService.Integration.Tests.ps1 new file mode 100644 index 0000000000..9de5490d9e --- /dev/null +++ b/tests/Integration/Commands/Uninstall-SqlDscReportingService.Integration.Tests.ps1 @@ -0,0 +1,66 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +Describe 'Uninstall-SqlDscReportingService' -Tag @('Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') { + BeforeAll { + Write-Verbose -Message ('Running integration test as user ''{0}''.' -f $env:UserName) -Verbose + + # Starting the Power BI Report Server service prior to running tests. + Start-Service -Name 'SQLServerReportingServices' -Verbose -ErrorAction 'Stop' + + $script:temporaryFolder = Get-TemporaryFolder + + # Get the path to the Reporting Services executable + $reportingServicesExecutable = Join-Path -Path $script:temporaryFolder -ChildPath 'SQLServerReportingServices.exe' + } + + It 'Should have the Reporting Services service running' { + $getServiceResult = Get-Service -Name 'SQLServerReportingServices' -ErrorAction 'Stop' + + $getServiceResult.Status | Should -Be 'Running' + } + + Context 'When uninstalling Reporting Services' { + It 'Should run the command without throwing' { + { + # Set splatting parameters for Uninstall-SqlDscReportingService + $uninstallSqlDscReportingServiceParameters = @{ + MediaPath = $reportingServicesExecutable + LogPath = Join-Path -Path $script:temporaryFolder -ChildPath 'SSRS_Uninstall.log' + SuppressRestart = $true + Verbose = $true + ErrorAction = 'Stop' + Force = $true + } + + Uninstall-SqlDscReportingService @uninstallSqlDscReportingServiceParameters + } | Should -Not -Throw + } + + It 'Should not have a SQL Server Reporting Services service' { + Get-Service -Name 'SQLServerReportingServices' -ErrorAction 'Ignore' | Should -BeNullOrEmpty + } + } +} diff --git a/tests/Integration/Commands/Uninstall-SqlDscServer.Integration.Tests.ps1 b/tests/Integration/Commands/Uninstall-SqlDscServer.Integration.Tests.ps1 index 424081b5e5..9f8b82f460 100644 --- a/tests/Integration/Commands/Uninstall-SqlDscServer.Integration.Tests.ps1 +++ b/tests/Integration/Commands/Uninstall-SqlDscServer.Integration.Tests.ps1 @@ -30,8 +30,6 @@ Describe 'Install-SqlDscServer' -Tag @('Integration_SQL2016', 'Integration_SQL20 # Starting the named instance SQL Server service prior to running tests. Start-Service -Name 'MSSQL$DSCSQLTEST' -Verbose -ErrorAction 'Stop' - - $computerName = Get-ComputerName } It 'Should have the named instance SQL Server service started' { diff --git a/tests/Unit/Private/Invoke-ReportServerSetupAction.Tests.ps1 b/tests/Unit/Private/Invoke-ReportServerSetupAction.Tests.ps1 index fef14a8209..8a1107a7c4 100644 --- a/tests/Unit/Private/Invoke-ReportServerSetupAction.Tests.ps1 +++ b/tests/Unit/Private/Invoke-ReportServerSetupAction.Tests.ps1 @@ -219,7 +219,7 @@ Describe 'Invoke-ReportServerSetupAction' -Tag 'Private' { @{ MockParameterName = 'Edition' MockParameterValue = 'Evaluation' - MockExpectedRegEx = '\/Edition=Evaluation' + MockExpectedRegEx = '\/Edition=Eval' } @{ MockParameterName = 'LogPath' @@ -565,7 +565,7 @@ Describe 'Invoke-ReportServerSetupAction' -Tag 'Private' { @{ MockParameterName = 'Edition' MockParameterValue = 'Evaluation' - MockExpectedRegEx = '\/Edition=Evaluation' + MockExpectedRegEx = '\/Edition=Eval' } @{ MockParameterName = 'LogPath' diff --git a/tests/Unit/Public/Install-SqlDscBIReportServer.Tests.ps1 b/tests/Unit/Public/Install-SqlDscBIReportServer.Tests.ps1 new file mode 100644 index 0000000000..016cee09ce --- /dev/null +++ b/tests/Unit/Public/Install-SqlDscBIReportServer.Tests.ps1 @@ -0,0 +1,179 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'Install-SqlDscBIReportServer' -Tag 'Public' { + It 'Should have the correct parameters in parameter set ' -ForEach @( + @{ + MockParameterSetName = '__AllParameterSets' + MockExpectedParameters = '[-MediaPath] [[-ProductKey] ] [[-Edition] ] [[-LogPath] ] [[-InstallFolder] ] [[-Timeout] ] -AcceptLicensingTerms [-EditionUpgrade] [-SuppressRestart] [-Force] [-WhatIf] [-Confirm] []' + } + ) { + $result = (Get-Command -Name 'Install-SqlDscBIReportServer').ParameterSets | + Where-Object -FilterScript { + $_.Name -eq $mockParameterSetName + } | + Select-Object -Property @( + @{ + Name = 'ParameterSetName' + Expression = { $_.Name } + }, + @{ + Name = 'ParameterListAsString' + Expression = { $_.ToString() } + } + ) + + $result.ParameterSetName | Should -Be $MockParameterSetName + $result.ParameterListAsString | Should -Be $MockExpectedParameters + } + + Context 'When installing SQL Server Power BI Report Server' { + BeforeAll { + Mock -CommandName Invoke-ReportServerSetupAction -RemoveParameterValidation @( + 'MediaPath' + 'InstallFolder' + ) + } + + Context 'When using mandatory parameters only' { + BeforeAll { + $mockDefaultParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\PowerBIReportServer.exe' + ErrorAction = 'Stop' + } + } + + Context 'When using parameter Confirm with value $false' { + It 'Should call the Invoke-ReportServerSetupAction with Install action' { + Install-SqlDscBIReportServer -Confirm:$false @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Install -eq $true -and + $AcceptLicensingTerms -eq $true -and + $MediaPath -eq '\PowerBIReportServer.exe' + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter Force' { + It 'Should call the Invoke-ReportServerSetupAction with Install action' { + Install-SqlDscBIReportServer -Force @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Install -eq $true -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter WhatIf' { + It 'Should call Invoke-ReportServerSetupAction' { + Install-SqlDscBIReportServer -WhatIf @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -Exactly -Times 1 -Scope It + } + } + } + + Context 'When using optional parameters' { + BeforeAll { + $installParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\PowerBIReportServer.exe' + ProductKey = '12345-12345-12345-12345-12345' + EditionUpgrade = $true + LogPath = 'C:\Logs\Install.log' + InstallFolder = 'C:\Program Files\Power BI Report Server' + SuppressRestart = $true + Timeout = 3600 + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass all parameters to Invoke-ReportServerSetupAction' { + Install-SqlDscBIReportServer @installParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Install -eq $true -and + $AcceptLicensingTerms -eq $true -and + $MediaPath -eq '\PowerBIReportServer.exe' -and + $ProductKey -eq '12345-12345-12345-12345-12345' -and + $EditionUpgrade -eq $true -and + $LogPath -eq 'C:\Logs\Install.log' -and + $InstallFolder -eq 'C:\Program Files\Power BI Report Server' -and + $SuppressRestart -eq $true -and + $Timeout -eq 3600 -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using Edition instead of ProductKey' { + BeforeAll { + $installParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\PowerBIReportServer.exe' + Edition = 'Evaluation' + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass the Edition parameter to Invoke-ReportServerSetupAction' { + Install-SqlDscBIReportServer @installParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Install -eq $true -and + $Edition -eq 'Evaluation' + } -Exactly -Times 1 -Scope It + } + } + } +} diff --git a/tests/Unit/Public/Install-SqlDscReportingService.Tests.ps1 b/tests/Unit/Public/Install-SqlDscReportingService.Tests.ps1 new file mode 100644 index 0000000000..7b55a653d4 --- /dev/null +++ b/tests/Unit/Public/Install-SqlDscReportingService.Tests.ps1 @@ -0,0 +1,179 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'Install-SqlDscReportingService' -Tag 'Public' { + It 'Should have the correct parameters in parameter set ' -ForEach @( + @{ + MockParameterSetName = '__AllParameterSets' + MockExpectedParameters = '[-MediaPath] [[-ProductKey] ] [[-Edition] ] [[-LogPath] ] [[-InstallFolder] ] [[-Timeout] ] -AcceptLicensingTerms [-EditionUpgrade] [-SuppressRestart] [-Force] [-WhatIf] [-Confirm] []' + } + ) { + $result = (Get-Command -Name 'Install-SqlDscReportingService').ParameterSets | + Where-Object -FilterScript { + $_.Name -eq $mockParameterSetName + } | + Select-Object -Property @( + @{ + Name = 'ParameterSetName' + Expression = { $_.Name } + }, + @{ + Name = 'ParameterListAsString' + Expression = { $_.ToString() } + } + ) + + $result.ParameterSetName | Should -Be $MockParameterSetName + $result.ParameterListAsString | Should -Be $MockExpectedParameters + } + + Context 'When installing SQL Server Reporting Services' { + BeforeAll { + Mock -CommandName Invoke-ReportServerSetupAction -RemoveParameterValidation @( + 'MediaPath' + 'InstallFolder' + ) + } + + Context 'When using mandatory parameters only' { + BeforeAll { + $mockDefaultParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\ReportingServices.exe' + ErrorAction = 'Stop' + } + } + + Context 'When using parameter Confirm with value $false' { + It 'Should call the Invoke-ReportServerSetupAction with Install action' { + Install-SqlDscReportingService -Confirm:$false @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Install -eq $true -and + $AcceptLicensingTerms -eq $true -and + $MediaPath -eq '\ReportingServices.exe' + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter Force' { + It 'Should call the Invoke-ReportServerSetupAction with Install action' { + Install-SqlDscReportingService -Force @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Install -eq $true -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter WhatIf' { + It 'Should call Invoke-ReportServerSetupAction' { + Install-SqlDscReportingService -WhatIf @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -Exactly -Times 1 -Scope It + } + } + } + + Context 'When using optional parameters' { + BeforeAll { + $installParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\ReportingServices.exe' + ProductKey = '12345-12345-12345-12345-12345' + EditionUpgrade = $true + LogPath = 'C:\Logs\Install.log' + InstallFolder = 'C:\Program Files\SSRS' + SuppressRestart = $true + Timeout = 3600 + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass all parameters to Invoke-ReportServerSetupAction' { + Install-SqlDscReportingService @installParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Install -eq $true -and + $AcceptLicensingTerms -eq $true -and + $MediaPath -eq '\ReportingServices.exe' -and + $ProductKey -eq '12345-12345-12345-12345-12345' -and + $EditionUpgrade -eq $true -and + $LogPath -eq 'C:\Logs\Install.log' -and + $InstallFolder -eq 'C:\Program Files\SSRS' -and + $SuppressRestart -eq $true -and + $Timeout -eq 3600 -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using Edition instead of ProductKey' { + BeforeAll { + $installParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\PowerBIReportServer.exe' + Edition = 'Evaluation' + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass the Edition parameter to Invoke-ReportServerSetupAction' { + Install-SqlDscReportingService @installParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Install -eq $true -and + $Edition -eq 'Evaluation' + } -Exactly -Times 1 -Scope It + } + } + } +} diff --git a/tests/Unit/Public/Install-SqlDscServer.Tests.ps1 b/tests/Unit/Public/Install-SqlDscServer.Tests.ps1 index e569bf6c43..031a9f94cf 100644 --- a/tests/Unit/Public/Install-SqlDscServer.Tests.ps1 +++ b/tests/Unit/Public/Install-SqlDscServer.Tests.ps1 @@ -652,102 +652,6 @@ Describe 'Install-SqlDscServer' -Tag 'Public' { } -Exactly -Times 1 -Scope It } } - - Context 'When specifying sensitive parameter ' -ForEach @( - @{ - MockParameterName = 'PBEngSvcPassword' - MockParameterValue = 'jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force # cspell: disable-line - MockExpectedRegEx = '\/PBENGSVCPASSWORD="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'PBDMSSvcPassword' # cspell: disable-line - MockParameterValue = ('jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force) # cspell: disable-line - MockExpectedRegEx = '\/PBDMSSVCPASSWORD="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'ProductKey' # cspell: disable-line - MockParameterValue = '22222-00000-00000-00000-00000' - MockExpectedRegEx = '\/PID="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'AgtSvcPassword' # cspell: disable-line - MockParameterValue = 'jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force # cspell: disable-line - MockExpectedRegEx = '\/AGTSVCPASSWORD="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'SAPwd' - MockParameterValue = 'jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force # cspell: disable-line - MockExpectedRegEx = '\/SAPWD="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'SqlSvcPassword' - MockParameterValue = 'jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force # cspell: disable-line - MockExpectedRegEx = '\/SQLSVCPASSWORD="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'ISSvcPassword' - MockParameterValue = 'jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force # cspell: disable-line - MockExpectedRegEx = '\/ISSVCPASSWORD="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'RSSvcPassword' - MockParameterValue = 'jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force # cspell: disable-line - MockExpectedRegEx = '\/RSSVCPASSWORD="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'AzureServicePrincipalSecret' - MockParameterValue = 'jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force # cspell: disable-line - MockExpectedRegEx = '\/AZURESERVICEPRINCIPALSECRET="\*{8}"' # cspell: disable-line - } - ) { - BeforeAll { - Mock -CommandName Write-Verbose - Mock -CommandName Start-SqlSetupProcess -MockWith { - return 0 - } -RemoveParameterValidation 'FilePath' - - $mockDefaultParameters = @{ - Install = $true - AcceptLicensingTerms = $true - MediaPath = '\SqlMedia' - InstanceName = 'INSTANCE' - # Intentionally using both upper- and lower-case in the value. - Features = 'SqlEngine' - SqlSysAdminAccounts = 'DOMAIN\User' - Force = $true - ErrorAction = 'Stop' - } - } - - BeforeEach { - $installSqlDscServerParameters = $mockDefaultParameters.Clone() - } - - It 'Should obfuscate the value in the verbose string' { - $installSqlDscServerParameters.$MockParameterName = $MockParameterValue - - # Redirect all verbose stream to $null to ge no output from ShouldProcess. - Install-SqlDscServer @installSqlDscServerParameters -Verbose 4> $null - - $mockVerboseMessage = InModuleScope -ScriptBlock { - $script:localizedData.Invoke_SetupAction_SetupArguments - } - - Should -Invoke -CommandName Write-Verbose -ParameterFilter { - # Only test the command that output the string that should be tested. - $correctMessage = $Message -match $mockVerboseMessage - - # Only test string if it is the correct verbose command - if ($correctMessage) - { - $Message | Should -MatchExactly $MockExpectedRegEx - } - - # Return wether the correct command was called or not. - $correctMessage - } -Exactly -Times 1 -Scope It - } - } } Context 'When setup action is ''Upgrade''' { @@ -2280,64 +2184,6 @@ Describe 'Install-SqlDscServer' -Tag 'Public' { } -Exactly -Times 1 -Scope It } } - - Context 'When specifying sensitive parameter ' -ForEach @( - @{ - MockParameterName = 'FarmPassword' - MockParameterValue = ('jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force) # cspell: disable-line - MockExpectedRegEx = '\/FARMPASSWORD="\*{8}"' # cspell: disable-line - } - @{ - MockParameterName = 'Passphrase' - MockParameterValue = ('jT7ELPbD2GGuvLmjABDL' | ConvertTo-SecureString -AsPlainText -Force) # cspell: disable-line - MockExpectedRegEx = '\/PASSPHRASE="\*{8}"' # cspell: disable-line - } - ) { - BeforeAll { - Mock -CommandName Write-Verbose - Mock -CommandName Start-SqlSetupProcess -MockWith { - return 0 - } - - $mockDefaultParameters = @{ - Install = $true - AcceptLicensingTerms = $true - MediaPath = '\SqlMedia' - Role = 'SPI_AS_NewFarm' - Force = $true - ErrorAction = 'Stop' - } - } - - BeforeEach { - $installSqlDscServerParameters = $mockDefaultParameters.Clone() - } - - It 'Should obfuscate the value in the verbose string' { - $installSqlDscServerParameters.$MockParameterName = $MockParameterValue - - # Redirect all verbose stream to $null to ge no output from ShouldProcess. - Install-SqlDscServer @installSqlDscServerParameters -Verbose 4> $null - - $mockVerboseMessage = InModuleScope -ScriptBlock { - $script:localizedData.Invoke_SetupAction_SetupArguments - } - - Should -Invoke -CommandName Write-Verbose -ParameterFilter { - # Only test the command that output the string that should be tested. - $correctMessage = $Message -match $mockVerboseMessage - - # Only test string if it is the correct verbose command - if ($correctMessage) - { - $Message | Should -MatchExactly $MockExpectedRegEx - } - - # Return wether the correct command was called or not. - $correctMessage - } -Exactly -Times 1 -Scope It - } - } } Context 'When role is ''AllFeatures_WithDefaults''' { diff --git a/tests/Unit/Public/Repair-SqlDscBIReportServer.Tests.ps1 b/tests/Unit/Public/Repair-SqlDscBIReportServer.Tests.ps1 new file mode 100644 index 0000000000..20e6628ca0 --- /dev/null +++ b/tests/Unit/Public/Repair-SqlDscBIReportServer.Tests.ps1 @@ -0,0 +1,179 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'Repair-SqlDscBIReportServer' -Tag 'Public' { + It 'Should have the correct parameters in parameter set ' -ForEach @( + @{ + MockParameterSetName = '__AllParameterSets' + MockExpectedParameters = '[-MediaPath] [[-ProductKey] ] [[-Edition] ] [[-LogPath] ] [[-InstallFolder] ] [[-Timeout] ] -AcceptLicensingTerms [-EditionUpgrade] [-SuppressRestart] [-Force] [-WhatIf] [-Confirm] []' + } + ) { + $result = (Get-Command -Name 'Repair-SqlDscBIReportServer').ParameterSets | + Where-Object -FilterScript { + $_.Name -eq $mockParameterSetName + } | + Select-Object -Property @( + @{ + Name = 'ParameterSetName' + Expression = { $_.Name } + }, + @{ + Name = 'ParameterListAsString' + Expression = { $_.ToString() } + } + ) + + $result.ParameterSetName | Should -Be $MockParameterSetName + $result.ParameterListAsString | Should -Be $MockExpectedParameters + } + + Context 'When repairing SQL Server Power BI Report Server' { + BeforeAll { + Mock -CommandName Invoke-ReportServerSetupAction -RemoveParameterValidation @( + 'MediaPath', + 'InstallFolder' + ) + } + + Context 'When using mandatory parameters only' { + BeforeAll { + $mockDefaultParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\PowerBIReportServer.exe' + ErrorAction = 'Stop' + } + } + + Context 'When using parameter Confirm with value $false' { + It 'Should call the Invoke-ReportServerSetupAction with Repair action' { + Repair-SqlDscBIReportServer -Confirm:$false @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Repair -eq $true -and + $AcceptLicensingTerms -eq $true -and + $MediaPath -eq '\PowerBIReportServer.exe' + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter Force' { + It 'Should call the Invoke-ReportServerSetupAction with Repair action' { + Repair-SqlDscBIReportServer -Force @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Repair -eq $true -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter WhatIf' { + It 'Should call Invoke-ReportServerSetupAction' { + Repair-SqlDscBIReportServer -WhatIf @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -Exactly -Times 1 -Scope It + } + } + } + + Context 'When using optional parameters' { + BeforeAll { + $repairParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\PowerBIReportServer.exe' + ProductKey = '12345-12345-12345-12345-12345' + EditionUpgrade = $true + LogPath = 'C:\Logs\Repair.log' + InstallFolder = 'C:\Program Files\Power BI Report Server' + SuppressRestart = $true + Timeout = 3600 + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass all parameters to Invoke-ReportServerSetupAction' { + Repair-SqlDscBIReportServer @repairParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Repair -eq $true -and + $AcceptLicensingTerms -eq $true -and + $MediaPath -eq '\PowerBIReportServer.exe' -and + $ProductKey -eq '12345-12345-12345-12345-12345' -and + $EditionUpgrade -eq $true -and + $LogPath -eq 'C:\Logs\Repair.log' -and + $InstallFolder -eq 'C:\Program Files\Power BI Report Server' -and + $SuppressRestart -eq $true -and + $Timeout -eq 3600 -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using Edition instead of ProductKey' { + BeforeAll { + $repairParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\PowerBIReportServer.exe' + Edition = 'Developer' + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass the Edition parameter to Invoke-ReportServerSetupAction' { + Repair-SqlDscBIReportServer @repairParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Repair -eq $true -and + $Edition -eq 'Developer' + } -Exactly -Times 1 -Scope It + } + } + } +} diff --git a/tests/Unit/Public/Repair-SqlDscReportingService.Tests.ps1 b/tests/Unit/Public/Repair-SqlDscReportingService.Tests.ps1 new file mode 100644 index 0000000000..e836f76f58 --- /dev/null +++ b/tests/Unit/Public/Repair-SqlDscReportingService.Tests.ps1 @@ -0,0 +1,179 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'Repair-SqlDscReportingService' -Tag 'Public' { + It 'Should have the correct parameters in parameter set ' -ForEach @( + @{ + MockParameterSetName = '__AllParameterSets' + MockExpectedParameters = '[-MediaPath] [[-ProductKey] ] [[-Edition] ] [[-LogPath] ] [[-InstallFolder] ] [[-Timeout] ] -AcceptLicensingTerms [-EditionUpgrade] [-SuppressRestart] [-Force] [-WhatIf] [-Confirm] []' + } + ) { + $result = (Get-Command -Name 'Repair-SqlDscReportingService').ParameterSets | + Where-Object -FilterScript { + $_.Name -eq $mockParameterSetName + } | + Select-Object -Property @( + @{ + Name = 'ParameterSetName' + Expression = { $_.Name } + }, + @{ + Name = 'ParameterListAsString' + Expression = { $_.ToString() } + } + ) + + $result.ParameterSetName | Should -Be $MockParameterSetName + $result.ParameterListAsString | Should -Be $MockExpectedParameters + } + + Context 'When repairing SQL Server Reporting Services' { + BeforeAll { + Mock -CommandName Invoke-ReportServerSetupAction -RemoveParameterValidation @( + 'MediaPath', + 'InstallFolder' + ) + } + + Context 'When using mandatory parameters only' { + BeforeAll { + $mockDefaultParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\ReportingServices.exe' + ErrorAction = 'Stop' + } + } + + Context 'When using parameter Confirm with value $false' { + It 'Should call the Invoke-ReportServerSetupAction with Repair action' { + Repair-SqlDscReportingService -Confirm:$false @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Repair -eq $true -and + $AcceptLicensingTerms -eq $true -and + $MediaPath -eq '\ReportingServices.exe' + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter Force' { + It 'Should call the Invoke-ReportServerSetupAction with Repair action' { + Repair-SqlDscReportingService -Force @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Repair -eq $true -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter WhatIf' { + It 'Should call Invoke-ReportServerSetupAction' { + Repair-SqlDscReportingService -WhatIf @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -Exactly -Times 1 -Scope It + } + } + } + + Context 'When using optional parameters' { + BeforeAll { + $repairParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\ReportingServices.exe' + ProductKey = '12345-12345-12345-12345-12345' + EditionUpgrade = $true + LogPath = 'C:\Logs\Repair.log' + InstallFolder = 'C:\Program Files\SSRS' + SuppressRestart = $true + Timeout = 3600 + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass all parameters to Invoke-ReportServerSetupAction' { + Repair-SqlDscReportingService @repairParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Repair -eq $true -and + $AcceptLicensingTerms -eq $true -and + $MediaPath -eq '\ReportingServices.exe' -and + $ProductKey -eq '12345-12345-12345-12345-12345' -and + $EditionUpgrade -eq $true -and + $LogPath -eq 'C:\Logs\Repair.log' -and + $InstallFolder -eq 'C:\Program Files\SSRS' -and + $SuppressRestart -eq $true -and + $Timeout -eq 3600 -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using Edition instead of ProductKey' { + BeforeAll { + $repairParameters = @{ + AcceptLicensingTerms = $true + MediaPath = '\PowerBIReportServer.exe' + Edition = 'Developer' + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass the Edition parameter to Invoke-ReportServerSetupAction' { + Repair-SqlDscReportingService @repairParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Repair -eq $true -and + $Edition -eq 'Developer' + } -Exactly -Times 1 -Scope It + } + } + } +} diff --git a/tests/Unit/Public/Save-SqlDscSqlServerMediaFile.Tests.ps1 b/tests/Unit/Public/Save-SqlDscSqlServerMediaFile.Tests.ps1 index 2237a3b939..6841b0246e 100644 --- a/tests/Unit/Public/Save-SqlDscSqlServerMediaFile.Tests.ps1 +++ b/tests/Unit/Public/Save-SqlDscSqlServerMediaFile.Tests.ps1 @@ -52,7 +52,7 @@ Describe 'Save-SqlDscSqlServerMediaFile' -Tag 'Public' { @{ MockParameterSetName = '__AllParameterSets' # cSpell: disable-next - MockExpectedParameters = '[-Url] [-DestinationPath] [[-FileName] ] [[-Language] ] [-Quiet] [-Force] [-WhatIf] [-Confirm] []' + MockExpectedParameters = '[-Url] [-DestinationPath] [[-FileName] ] [[-Language] ] [-Quiet] [-Force] [-SkipExecution] [-WhatIf] [-Confirm] []' } ) { $result = (Get-Command -Name 'Save-SqlDscSqlServerMediaFile').ParameterSets | diff --git a/tests/Unit/Public/Uninstall-SqlDscBIReportServer.Tests.ps1 b/tests/Unit/Public/Uninstall-SqlDscBIReportServer.Tests.ps1 new file mode 100644 index 0000000000..8cf1769e1b --- /dev/null +++ b/tests/Unit/Public/Uninstall-SqlDscBIReportServer.Tests.ps1 @@ -0,0 +1,147 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'Uninstall-SqlDscBIReportServer' -Tag 'Public' { + It 'Should have the correct parameters in parameter set ' -ForEach @( + @{ + MockParameterSetName = '__AllParameterSets' + MockExpectedParameters = '[-MediaPath] [[-LogPath] ] [[-Timeout] ] [-SuppressRestart] [-Force] [-WhatIf] [-Confirm] []' + } + ) { + $result = (Get-Command -Name 'Uninstall-SqlDscBIReportServer').ParameterSets | + Where-Object -FilterScript { + $_.Name -eq $mockParameterSetName + } | + Select-Object -Property @( + @{ + Name = 'ParameterSetName' + Expression = { $_.Name } + }, + @{ + Name = 'ParameterListAsString' + Expression = { $_.ToString() } + } + ) + + $result.ParameterSetName | Should -Be $MockParameterSetName + $result.ParameterListAsString | Should -Be $MockExpectedParameters + } + + Context 'When uninstalling SQL Server BI Report Server' { + BeforeAll { + Mock -CommandName Invoke-ReportServerSetupAction -RemoveParameterValidation @( + 'MediaPath' + ) + } + + Context 'When using mandatory parameters only' { + BeforeAll { + $mockDefaultParameters = @{ + MediaPath = '\PowerBIReportServer.exe' + ErrorAction = 'Stop' + } + } + + Context 'When using parameter Confirm with value $false' { + It 'Should call the Invoke-ReportServerSetupAction with Uninstall action' { + Uninstall-SqlDscBIReportServer -Confirm:$false @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Uninstall -eq $true -and + $MediaPath -eq '\PowerBIReportServer.exe' + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter Force' { + It 'Should call the Invoke-ReportServerSetupAction with Uninstall action' { + Uninstall-SqlDscBIReportServer -Force @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Uninstall -eq $true -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter WhatIf' { + It 'Should call Invoke-ReportServerSetupAction' { + Uninstall-SqlDscBIReportServer -WhatIf @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -Exactly -Times 1 -Scope It + } + } + } + + Context 'When using optional parameters' { + BeforeAll { + $uninstallParameters = @{ + MediaPath = '\PowerBIReportServer.exe' + LogPath = 'C:\Logs\Uninstall.log' + SuppressRestart = $true + Timeout = 3600 + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass all parameters to Invoke-ReportServerSetupAction' { + Uninstall-SqlDscBIReportServer @uninstallParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Uninstall -eq $true -and + $MediaPath -eq '\PowerBIReportServer.exe' -and + $LogPath -eq 'C:\Logs\Uninstall.log' -and + $SuppressRestart -eq $true -and + $Timeout -eq 3600 -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + } +} diff --git a/tests/Unit/Public/Uninstall-SqlDscReportingService.Tests.ps1 b/tests/Unit/Public/Uninstall-SqlDscReportingService.Tests.ps1 new file mode 100644 index 0000000000..6816b3958b --- /dev/null +++ b/tests/Unit/Public/Uninstall-SqlDscReportingService.Tests.ps1 @@ -0,0 +1,147 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'Uninstall-SqlDscReportingService' -Tag 'Public' { + It 'Should have the correct parameters in parameter set ' -ForEach @( + @{ + MockParameterSetName = '__AllParameterSets' + MockExpectedParameters = '[-MediaPath] [[-LogPath] ] [[-Timeout] ] [-SuppressRestart] [-Force] [-WhatIf] [-Confirm] []' + } + ) { + $result = (Get-Command -Name 'Uninstall-SqlDscReportingService').ParameterSets | + Where-Object -FilterScript { + $_.Name -eq $mockParameterSetName + } | + Select-Object -Property @( + @{ + Name = 'ParameterSetName' + Expression = { $_.Name } + }, + @{ + Name = 'ParameterListAsString' + Expression = { $_.ToString() } + } + ) + + $result.ParameterSetName | Should -Be $MockParameterSetName + $result.ParameterListAsString | Should -Be $MockExpectedParameters + } + + Context 'When uninstalling SQL Server Reporting Services' { + BeforeAll { + Mock -CommandName Invoke-ReportServerSetupAction -RemoveParameterValidation @( + 'MediaPath' + ) + } + + Context 'When using mandatory parameters only' { + BeforeAll { + $mockDefaultParameters = @{ + MediaPath = '\ReportingServices.exe' + ErrorAction = 'Stop' + } + } + + Context 'When using parameter Confirm with value $false' { + It 'Should call the Invoke-ReportServerSetupAction with Uninstall action' { + Uninstall-SqlDscReportingService -Confirm:$false @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Uninstall -eq $true -and + $MediaPath -eq '\ReportingServices.exe' + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter Force' { + It 'Should call the Invoke-ReportServerSetupAction with Uninstall action' { + Uninstall-SqlDscReportingService -Force @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Uninstall -eq $true -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + + Context 'When using parameter WhatIf' { + It 'Should call Invoke-ReportServerSetupAction' { + Uninstall-SqlDscReportingService -WhatIf @mockDefaultParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -Exactly -Times 1 -Scope It + } + } + } + + Context 'When using optional parameters' { + BeforeAll { + $uninstallParameters = @{ + MediaPath = '\PowerBIReportServer.exe' + LogPath = 'C:\Logs\Uninstall.log' + SuppressRestart = $true + Timeout = 3600 + Force = $true + ErrorAction = 'Stop' + } + } + + It 'Should pass all parameters to Invoke-ReportServerSetupAction' { + Uninstall-SqlDscReportingService @uninstallParameters + + Should -Invoke -CommandName Invoke-ReportServerSetupAction -ParameterFilter { + $Uninstall -eq $true -and + $MediaPath -eq '\PowerBIReportServer.exe' -and + $LogPath -eq 'C:\Logs\Uninstall.log' -and + $SuppressRestart -eq $true -and + $Timeout -eq 3600 -and + $Force -eq $true + } -Exactly -Times 1 -Scope It + } + } + } +}