Skip to content

Commit a8befef

Browse files
authored
Get-SqlDscRSSetupConfiguration: Add function to retrieve Report Server setup configuration (#2074)
1 parent cbb005b commit a8befef

14 files changed

+1285
-31
lines changed

.github/copilot-instructions.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# Specific instructions for the PowerShell module project SqlServerDsc
2+
3+
Assume that the word "command" references to a public command, and the word
4+
"function" references to a private function.
5+
6+
PowerShell commands that should be public should always have its separate
7+
script file and the the command name as the file name with the .ps1 extension,
8+
these files shall always be placed in the folder source/Public.
9+
10+
Public commands may use private functions to move out logic that can be
11+
reused by other public commands, so move out any logic that can be deemed
12+
reusable. Private functions should always have its separate script file and
13+
the the function name as the file name with the .ps1 extension, these files
14+
shall always be placed in the folder source/Private.
15+
16+
Comment-based help should be added to each public command and private functions.
17+
The comment-based help should always be before the function-statement. Each
18+
comment-based help keyword should be indented with 4 spaces and each keywords
19+
text should be indented 8 spaces. The text for keyword .DESCRIPTION should
20+
be descriptive and must have a length greater than 40 characters. A comment-based
21+
help must have at least one example, but preferably more examples to showcase
22+
all possible parameter sets and different parameter combinations.
23+
24+
All message strings for Write-Debug, Write-Verbose, Write-Error, Write-Warning
25+
and other error messages in public commands and private functions should be
26+
localized using localized string keys. You should always add all localized
27+
strings for public commands and private functions in the source/en-US/SqlServerDsc.strings.psd1
28+
file, re-use the same pattern for new string keys. Localized string key names
29+
should always be prefixed with the function name but use underscore as word
30+
separator. Always assume that all localized string keys have already been
31+
assigned to the variable $script:localizedData.
32+
33+
All tests should use the Pester framework and use Pester v5.0 syntax.
34+
35+
Never test, mock or use `Should -Invoke` for `Write-Verbose` and `Write-Debug`
36+
regardless of other instructions.
37+
38+
Test code should never be added outside of the `Describe` block.
39+
40+
Unit tests should be added for all public commands and private functions.
41+
The unit tests for public command should be placed in the folder tests/Unit/Public
42+
and the unit tests for private functions should be placed in the folder
43+
tests/Unit/Private. The unit tests should be named after the public command
44+
or private function they are testing, but should have the suffix .Tests.ps1.
45+
The unit tests should be written to cover all possible scenarios and code paths,
46+
ensuring that both edge cases and common use cases are tested.
47+
48+
There should only be one Pester `Describe` block per test file, and the name of
49+
the `Describe` block should be the same as the name of the public command or
50+
private function being tested. Each scenario or code path being tested should
51+
have its own Pester `Context` block that starts with the phrase 'When'. Use
52+
nested `Context` blocks to split up test cases and improve tests readability.
53+
Pester `It` block descriptions should start with the phrase 'Should'. `It`
54+
blocks must always call the command or function being tested and result and
55+
outcomes should be kept in the same `It` block. `BeforeAll` and `BeforeEach`
56+
blocks should never call the command or function being tested.
57+
58+
The `BeforeAll`, `BeforeEach`, `AfterAll` and `AfterEach` blocks should be
59+
used inside the `Context` block as near as possible to the `It` block that
60+
will use the mocked test setup and teardown. The `BeforeAll` block should
61+
be used to set up any necessary test data or mocking, and the `AfterAll`
62+
block can be used to clean up any test data. The `BeforeEach` and `AfterEach`
63+
blocks should be used sparingly. It is okay to duplicated code in `BeforeAll`
64+
and `BeforeEach` blocks inside different `Context` blocks to help with
65+
readability and understanding of the test cases, to keep the test setup
66+
and teardown as close to the test case as possible.
67+
68+
Use localized strings in the tests only when necessary. You can assign the
69+
localized string to a mock variable by and get the localized string key
70+
from the $script:localizedData variable inside a `InModuleScope` block.
71+
An example to get a localized string key from the $script:localizedData variable:
72+
73+
```powershell
74+
$mockLocalizedStringText = InModuleScope -ScriptBlock { $script:localizedData.LocalizedStringKey }
75+
```
76+
77+
Files that need to be mocked should be created in Pesters test drive. The
78+
variable `$TestDrive` holds the path to the test drive. The `$TestDrive` is a
79+
temporary drive that is created for each test run and is automatically
80+
cleaned up after the test run is complete.
81+
82+
All unit tests should should use this code block prior to the `Describe` block
83+
which will set up the test environment and load the correct module being tested:
84+
85+
```powershell
86+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
87+
param ()
88+
89+
BeforeDiscovery {
90+
try
91+
{
92+
if (-not (Get-Module -Name 'DscResource.Test'))
93+
{
94+
# Assumes dependencies has been resolved, so if this module is not available, run 'noop' task.
95+
if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable))
96+
{
97+
# Redirect all streams to $null, except the error stream (stream 2)
98+
& "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null
99+
}
100+
101+
# If the dependencies has not been resolved, this will throw an error.
102+
Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop'
103+
}
104+
}
105+
catch [System.IO.FileNotFoundException]
106+
{
107+
throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.'
108+
}
109+
}
110+
111+
BeforeAll {
112+
$script:dscModuleName = 'SqlServerDsc'
113+
114+
$env:SqlServerDscCI = $true
115+
116+
Import-Module -Name $script:dscModuleName
117+
118+
$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName
119+
$PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName
120+
$PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName
121+
}
122+
123+
AfterAll {
124+
$PSDefaultParameterValues.Remove('InModuleScope:ModuleName')
125+
$PSDefaultParameterValues.Remove('Mock:ModuleName')
126+
$PSDefaultParameterValues.Remove('Should:ModuleName')
127+
128+
# Unload the module being tested so that it doesn't impact any other tests.
129+
Get-Module -Name $script:dscModuleName -All | Remove-Module -Force
130+
131+
Remove-Item -Path 'env:SqlServerDscCI'
132+
}
133+
```
134+
135+
Integration tests should be added for all public commands. Integration must
136+
never mock any command but run the command in a real environment. The integration
137+
tests should be placed in the folder tests/Integration/Commands and the
138+
integration tests should be named after the public command they are testing,
139+
but should have the suffix .Integration.Tests.ps1. The integration tests should be
140+
written to cover all possible scenarios and code paths, ensuring that both
141+
edge cases and common use cases are tested. The integration tests should
142+
also be written to test the command in a real environment, using real
143+
resources and dependencies.
144+
145+
The module being tested should not be imported in the integration tests.
146+
All integration tests should should use this code block prior to the `Describe`
147+
block which will set up the test environment and will make sure the correct
148+
module is available for testing:
149+
150+
```powershell
151+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]
152+
param ()
153+
154+
BeforeDiscovery {
155+
try
156+
{
157+
if (-not (Get-Module -Name 'DscResource.Test'))
158+
{
159+
# Assumes dependencies has been resolved, so if this module is not available, run 'noop' task.
160+
if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable))
161+
{
162+
# Redirect all streams to $null, except the error stream (stream 2)
163+
& "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null
164+
}
165+
166+
# If the dependencies has not been resolved, this will throw an error.
167+
Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop'
168+
}
169+
}
170+
catch [System.IO.FileNotFoundException]
171+
{
172+
throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.'
173+
}
174+
}
175+
```

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,6 @@
111111
"pester.suppressCodeLensNotice": true,
112112
"markdownlint.ignore": [
113113
".github/CODEOWNERS"
114-
]
114+
],
115+
"github.copilot.chat.codeGeneration.useInstructionFiles": true
115116
}

CHANGELOG.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
### Added
1515

1616
- Public commands:
17-
- `Install-SqlDscReportingService`
18-
- `Install-SqlDscBIReportServer`
19-
- `Repair-SqlDscReportingService`
20-
- `Repair-SqlDscBIReportServer`
21-
- `Uninstall-SqlDscReportingService`
22-
- `Uninstall-SqlDscBIReportServer`
17+
- `Get-SqlDscInstalledInstance` to retrieve installed SQL instances.
18+
- `Get-SqlDscRSSetupConfiguration` to retrieve the setup configuration of
19+
SQL Server Reporting Services or Power BI Report Server ([issue #2072](https://github.com/dsccommunity/SqlServerDsc/issues/2072)).
20+
- `Install-SqlDscReportingService` to install SQL Server Reporting Services
21+
([issue #2010](https://github.com/dsccommunity/SqlServerDsc/issues/2010)).
22+
- `Install-SqlDscBIReportServer` to install SQL Server BI Report Server.
23+
([issue #2010](https://github.com/dsccommunity/SqlServerDsc/issues/2010)).
24+
- `Repair-SqlDscReportingService` to repair an already installed SQL Server
25+
Reporting Services ([issue #2064](https://github.com/dsccommunity/SqlServerDsc/issues/2064)).
26+
- `Repair-SqlDscBIReportServer` to repair an already installed SQL Server
27+
BI Report Server ([issue #2064](https://github.com/dsccommunity/SqlServerDsc/issues/2064)).
28+
- `Uninstall-SqlDscReportingService` to uninstall SQL Server Reporting
29+
Services ([issue #2065](https://github.com/dsccommunity/SqlServerDsc/issues/2065)).
30+
- `Uninstall-SqlDscBIReportServer` to uninstall SQL Server BI Report Server
31+
([issue #2065](https://github.com/dsccommunity/SqlServerDsc/issues/2065)).
2332
- Private function:
24-
- `Invoke-ReportServerSetupAction`
33+
- `Invoke-ReportServerSetupAction` to run setup actions for Reporting
34+
Services and Power BI Report Server.
35+
- Added new instructions for GitHub Copilot that might assist when developing
36+
command and private functions in the module. More instructions should be
37+
added as needed to help generated code and tests.
2538

2639
### Changed
2740

azure-pipelines.yml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ stages:
119119
testResultsFormat: 'NUnit'
120120
testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml'
121121
testRunTitle: 'HQRM'
122+
122123
- job: Test_Unit
123124
displayName: 'Unit'
124125
pool:
@@ -155,6 +156,7 @@ stages:
155156
targetPath: '$(buildFolderName)/$(testResultFolderName)/'
156157
artifactName: $(testArtifactName)
157158
parallel: true
159+
158160
- job: Code_Coverage
159161
displayName: 'Publish Code Coverage'
160162
dependsOn: Test_Unit
@@ -277,22 +279,22 @@ stages:
277279
matrix:
278280
SQL2017_WIN2019:
279281
JOB_VMIMAGE: 'windows-2019'
280-
TEST_CONFIGURATION: 'Integration_SQL2017'
282+
TEST_CONFIGURATION: 'Integration_SQL2017_RS'
281283
SQL2017_WIN2022:
282284
JOB_VMIMAGE: 'windows-2022'
283-
TEST_CONFIGURATION: 'Integration_SQL2017'
285+
TEST_CONFIGURATION: 'Integration_SQL2017_RS'
284286
SQL2019_WIN2019:
285287
JOB_VMIMAGE: 'windows-2019'
286-
TEST_CONFIGURATION: 'Integration_SQL2019'
288+
TEST_CONFIGURATION: 'Integration_SQL2019_RS'
287289
SQL2019_WIN2022:
288290
JOB_VMIMAGE: 'windows-2022'
289-
TEST_CONFIGURATION: 'Integration_SQL2019'
291+
TEST_CONFIGURATION: 'Integration_SQL2019_RS'
290292
SQL2022_WIN2019:
291293
JOB_VMIMAGE: 'windows-2019'
292-
TEST_CONFIGURATION: 'Integration_SQL2022'
294+
TEST_CONFIGURATION: 'Integration_SQL2022_RS'
293295
SQL2022_WIN2022:
294296
JOB_VMIMAGE: 'windows-2022'
295-
TEST_CONFIGURATION: 'Integration_SQL2022'
297+
TEST_CONFIGURATION: 'Integration_SQL2022_RS'
296298
pool:
297299
vmImage: $(JOB_VMIMAGE)
298300
timeoutInMinutes: 0
@@ -323,6 +325,9 @@ stages:
323325
'tests/Integration/Commands/Prerequisites.Integration.Tests.ps1'
324326
# Group 1
325327
'tests/Integration/Commands/Install-SqlDscReportingService.Integration.Tests.ps1'
328+
# Group 2
329+
'tests/Integration/Commands/Get-SqlDscInstalledInstance.Integration.Tests.ps1'
330+
'tests/Integration/Commands/Get-SqlDscRSSetupConfiguration.Integration.Tests.ps1'
326331
# Group 8
327332
'tests/Integration/Commands/Repair-SqlDscReportingService.Integration.Tests.ps1'
328333
# Group 9
@@ -382,6 +387,9 @@ stages:
382387
'tests/Integration/Commands/Prerequisites.Integration.Tests.ps1'
383388
# Group 1
384389
'tests/Integration/Commands/Install-SqlDscBIReportServer.Integration.Tests.ps1'
390+
# Group 2
391+
'tests/Integration/Commands/Get-SqlDscInstalledInstance.Integration.Tests.ps1'
392+
'tests/Integration/Commands/Get-SqlDscRSSetupConfiguration.Integration.Tests.ps1'
385393
# Group 8
386394
'tests/Integration/Commands/Repair-SqlDscBIReportServer.Integration.Tests.ps1'
387395
# Group 9
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<#
2+
.SYNOPSIS
3+
Returns the installed instances on the current node.
4+
5+
.DESCRIPTION
6+
Returns the installed instances on the current node.
7+
8+
.PARAMETER InstanceName
9+
Specifies the instance name to return instances for.
10+
11+
.PARAMETER ServiceType
12+
Specifies the service type to filter instances by. Valid values are
13+
'DatabaseEngine', 'AnalysisServices', and 'ReportingServices'.
14+
15+
.OUTPUTS
16+
`[System.Object[]]`
17+
18+
.EXAMPLE
19+
Get-SqlDscInstalledInstance
20+
21+
Returns all installed instances.
22+
#>
23+
function Get-SqlDscInstalledInstance
24+
{
25+
[CmdletBinding()]
26+
[OutputType([System.Object[]])]
27+
param
28+
(
29+
[Parameter()]
30+
[System.String]
31+
$InstanceName,
32+
33+
[Parameter()]
34+
[ValidateSet('DatabaseEngine', 'AnalysisServices', 'ReportingServices')]
35+
[System.String[]]
36+
$ServiceType
37+
)
38+
39+
if ($PSBoundParameters.ContainsKey('InstanceName'))
40+
{
41+
$InstanceName = $InstanceName.ToUpper()
42+
}
43+
44+
$instances = @()
45+
46+
$installedServiceType = Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names' -ErrorAction 'SilentlyContinue'
47+
48+
foreach ($currentServiceType in $installedServiceType)
49+
{
50+
$serviceTypeName = switch ($currentServiceType.PSChildName)
51+
{
52+
'OLAP'
53+
{
54+
'AnalysisServices'
55+
56+
break
57+
}
58+
59+
'SQL'
60+
{
61+
'DatabaseEngine'
62+
63+
break
64+
}
65+
66+
'RS'
67+
{
68+
'ReportingServices'
69+
70+
break
71+
}
72+
}
73+
74+
if ($PSBoundParameters.ContainsKey('ServiceType') -and $serviceTypeName -notin $ServiceType)
75+
{
76+
continue
77+
}
78+
79+
$instanceNames = $currentServiceType.GetValueNames()
80+
81+
foreach ($currentInstanceName in $instanceNames)
82+
{
83+
if ($PSBoundParameters.ContainsKey('InstanceName') -and $currentInstanceName -ne $InstanceName)
84+
{
85+
continue
86+
}
87+
88+
$foundInstance = [PSCustomObject] @{
89+
ServiceType = $serviceTypeName
90+
InstanceName = $currentInstanceName
91+
InstanceId = $currentServiceType.GetValue($currentInstanceName)
92+
}
93+
94+
$instances += $foundInstance
95+
}
96+
}
97+
98+
return $instances
99+
}

0 commit comments

Comments
 (0)