Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d818f58
Add functions to manage report server database creation and permissions
johlju Jan 3, 2026
b9a3a66
Add System.ComponentModel.TypeConverter to referenced assemblies in S…
johlju Jan 3, 2026
7204a62
Fix comment-based help formatting and enhance QA tests for example co…
johlju Jan 3, 2026
a62b1a9
Fix comment-based help formatting by removing blank lines in example …
johlju Jan 3, 2026
ab8d82c
Fix comment-based help formatting by removing blank lines in example …
johlju Jan 3, 2026
ab908e1
Fix Reporting Services integration test tags and update README for cl…
johlju Jan 3, 2026
2b06005
Fix error handling in Invoke-RsCimMethod to provide descriptive fallb…
johlju Jan 3, 2026
d5f56cf
Fix error handling in Set-SqlDscRSDatabaseConnection by adding -Error…
johlju Jan 4, 2026
8a4938c
Refactor comment-based help structure tests by removing unused variab…
johlju Jan 4, 2026
c4fe9bf
Merge branch 'main' into f/issue-#2021
johlju Jan 4, 2026
6173d16
Add Get-HResultMessage function for translating HRESULT codes and enh…
johlju Jan 4, 2026
a077d47
Add Import-SqlDscPreferredModule to ensure SMO types are loaded in in…
johlju Jan 4, 2026
ed17306
Add "HRESULT" to cSpell words list for improved spell checking
johlju Jan 4, 2026
2cff608
Add notes to Get-HResultMessage function regarding error message reli…
johlju Jan 4, 2026
008e0fb
Enhance Request-SqlDscRSDatabaseScript to check if Reporting Services…
johlju Jan 4, 2026
3aa8e07
Refactor Request-SqlDscRSDatabaseRightsScript and related tests to re…
johlju Jan 4, 2026
a999afc
Refactor tests for Set-SqlDscRSDatabaseConnection to simplify asserti…
johlju Jan 4, 2026
4ce933b
Merge branch 'main' into f/issue-#2021
johlju Jan 4, 2026
a52e4f5
Refactor Set-TargetResource to use public commands for database scrip…
johlju Jan 4, 2026
3c854db
Enhance SqlRS tests by adding WindowsServiceIdentityActual property a…
johlju Jan 5, 2026
c8fbb1b
Update WindowsServiceIdentityActual property in Set-TargetResource te…
johlju Jan 5, 2026
695f3a0
Merge branch 'main' into f/issue-#2021
johlju Jan 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@
"varchar",
"maxdop",
"hotfixes",
"checkpointing"
"checkpointing",
"HRESULT"
],
"cSpell.ignorePaths": [
".git"
Expand Down
74 changes: 71 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added public command `Request-SqlDscRSDatabaseScript` to generate T-SQL scripts
for creating report server databases. Wraps the `GenerateDatabaseCreationScript`
CIM method and supports configuring database name, language (LCID), and
SharePoint mode ([issue #2017](https://github.com/dsccommunity/SqlServerDsc/issues/2017)).
- Added public command `Request-SqlDscRSDatabaseRightsScript` to generate T-SQL
scripts for granting permissions on report server databases. Wraps the
`GenerateDatabaseRightsScript` CIM method and supports configuring database
name, user name, remote connections, and Windows/SQL authentication types
([issue #2019](https://github.com/dsccommunity/SqlServerDsc/issues/2019)).
- Added public command `Set-SqlDscRSDatabaseConnection` to set
the report server database connection for SQL Server Reporting Services or
Power BI Report Server. Wraps the `SetDatabaseConnection` CIM method and
supports Windows, SQL Server, and Service Account authentication types
([issue #2021](https://github.com/dsccommunity/SqlServerDsc/issues/2021)).
- Added public command `Set-SqlDscRSVirtualDirectory` to set the virtual directory
for Reporting Services applications. Wraps the `SetVirtualDirectory` CIM method
and supports ReportServerWebService, ReportServerWebApp, and ReportManager
Expand Down Expand Up @@ -47,6 +61,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Services configuration instances with consistent error handling. This function
is used by `Enable-SqlDscRsSecureConnection`, `Disable-SqlDscRsSecureConnection`,
and the `SqlRS` resource.
- Added private function `Get-HResultMessage` to translate common Windows HRESULT
error codes into human-readable messages. Used by `Invoke-RsCimMethod` to
provide actionable error messages when Reporting Services CIM methods fail
without detailed error information.
- `Invoke-ReportServerSetupAction`
- Now uses `Format-Path` with `-ExpandEnvironmentVariable` to expand environment
variables in all path parameters (`MediaPath`, `LogPath`, `InstallFolder`)
Expand Down Expand Up @@ -172,6 +190,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- `Invoke-RsCimMethod`
- Enhanced error messages to include human-readable translations of common
HRESULT error codes. When Reporting Services CIM methods fail without
detailed error information, the error message now includes actionable
guidance based on the HRESULT code (e.g., service not running, access
denied, logon type not granted).
- Fixed error handling to properly surface error details. Previously, when
the `ExtendedErrors` property existed but was empty, the error message
would show an empty error description. Now it correctly falls back to
the `Error` property and provides a descriptive fallback message if
neither property contains error details.
- Prerequisites Integration Tests
- Fixed missing RS (Reporting Services) integration test tags on Context blocks
that create local Windows users, service accounts, and groups. Added tags
`Integration_SQL2017_RS`, `Integration_SQL2019_RS`, and `Integration_SQL2022_RS`
to ensure these prerequisites run before Reporting Services integration tests.
- `New-SqlDscFileGroup`
- Fixed comment-based help example formatting by moving inline comment
to the description text.
- QA Tests
- Added new test to detect comments within multi-line example code blocks
in comment-based help. Comments in the code portion of `.EXAMPLE` blocks
cause PlatyPS documentation generation to fail with "Expect Heading" errors.
- Added new test to detect blank lines within multi-line example code blocks
in comment-based help. Blank lines within the code portion of `.EXAMPLE`
blocks cause similar issues with documentation generation.
- `Deny-SqlDscServerPermission`
- Fixed comment-based help example formatting by removing blank lines
within code blocks that would cause documentation generation issues.
- `Get-SqlDscServerPermission`
- Fixed comment-based help example formatting by removing blank lines
within code blocks that would cause documentation generation issues.
- `Grant-SqlDscServerPermission`
- Fixed comment-based help example formatting by removing blank lines
within code blocks that would cause documentation generation issues.
- `New-SqlDscDatabase`
- Fixed comment-based help example formatting by removing blank lines
within code blocks.
- `New-SqlDscDatabaseSnapshot`
- Fixed comment-based help example formatting by removing blank lines
within code blocks.
- `Revoke-SqlDscServerPermission`
- Fixed comment-based help example formatting by removing blank lines
within code blocks.
- `Set-SqlDscDatabasePermission`
- Fixed comment-based help example formatting by removing blank lines
within code blocks.
- `Set-SqlDscServerPermission`
- Fixed comment-based help example formatting by removing blank lines
within code blocks.
- `Test-SqlDscServerPermission`
- Fixed comment-based help example formatting by removing blank lines
within code blocks.
- Unit Tests
- Fixed PowerShell class type identity issues that caused "Cannot convert
'Type' to 'Type'" errors when running multiple test files in the same
Expand Down Expand Up @@ -231,9 +302,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Set-SqlDscDatabaseProperty`
- Updated comment-based help to reference correct enum values.
- Added SQL Server version requirements to version-specific parameter help.

### Fixed

- `Set-SqlDscServerPermission`
- Fixed an issue where unspecified permission parameters would incorrectly
revoke existing permissions. The command now only processes permission
Expand Down
8 changes: 8 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ stages:
# Run the integration tests in a specific group order.
# Group 0
'tests/Integration/Commands/Prerequisites.Integration.Tests.ps1'
'tests/Integration/Commands/Prerequisites.RSDB.Integration.Tests.ps1'
'tests/Integration/Commands/Save-SqlDscSqlServerMediaFile.Integration.Tests.ps1'
'tests/Integration/Commands/Import-SqlDscPreferredModule.Integration.Tests.ps1'
# Group 1
Expand All @@ -535,6 +536,8 @@ stages:
'tests/Integration/Commands/Get-SqlDscRSPackage.Integration.Tests.ps1'
'tests/Integration/Commands/Get-SqlDscRSSetupConfiguration.Integration.Tests.ps1'
'tests/Integration/Commands/Test-SqlDscRSInstalled.Integration.Tests.ps1'
'tests/Integration/Commands/Request-SqlDscRSDatabaseScript.Integration.Tests.ps1'
'tests/Integration/Commands/Request-SqlDscRSDatabaseRightsScript.Integration.Tests.ps1'
# Group 3
'tests/Integration/Commands/Get-SqlDscRSConfiguration.Integration.Tests.ps1'
'tests/Integration/Commands/Enable-SqlDscRsSecureConnection.Integration.Tests.ps1'
Expand All @@ -544,6 +547,7 @@ stages:
'tests/Integration/Commands/Add-SqlDscRSUrlReservation.Integration.Tests.ps1'
'tests/Integration/Commands/Remove-SqlDscRSUrlReservation.Integration.Tests.ps1'
'tests/Integration/Commands/Set-SqlDscRSUrlReservation.Integration.Tests.ps1'
'tests/Integration/Commands/Set-SqlDscRSDatabaseConnection.Integration.Tests.ps1'
# Group 8
'tests/Integration/Commands/Repair-SqlDscReportingService.Integration.Tests.ps1'
# Group 9
Expand Down Expand Up @@ -601,6 +605,7 @@ stages:
# Run the integration tests in a specific group order.
# Group 0
'tests/Integration/Commands/Prerequisites.Integration.Tests.ps1'
'tests/Integration/Commands/Prerequisites.RSDB.Integration.Tests.ps1'
'tests/Integration/Commands/Save-SqlDscSqlServerMediaFile.Integration.Tests.ps1'
'tests/Integration/Commands/Import-SqlDscPreferredModule.Integration.Tests.ps1'
# Group 1
Expand All @@ -610,6 +615,8 @@ stages:
'tests/Integration/Commands/Get-SqlDscRSPackage.Integration.Tests.ps1'
'tests/Integration/Commands/Get-SqlDscRSSetupConfiguration.Integration.Tests.ps1'
'tests/Integration/Commands/Test-SqlDscRSInstalled.Integration.Tests.ps1'
'tests/Integration/Commands/Request-SqlDscRSDatabaseScript.Integration.Tests.ps1'
'tests/Integration/Commands/Request-SqlDscRSDatabaseRightsScript.Integration.Tests.ps1'
# Group 3
'tests/Integration/Commands/Get-SqlDscRSConfiguration.Integration.Tests.ps1'
'tests/Integration/Commands/Enable-SqlDscRsSecureConnection.Integration.Tests.ps1'
Expand All @@ -619,6 +626,7 @@ stages:
'tests/Integration/Commands/Add-SqlDscRSUrlReservation.Integration.Tests.ps1'
'tests/Integration/Commands/Remove-SqlDscRSUrlReservation.Integration.Tests.ps1'
'tests/Integration/Commands/Set-SqlDscRSUrlReservation.Integration.Tests.ps1'
'tests/Integration/Commands/Set-SqlDscRSDatabaseConnection.Integration.Tests.ps1'
# Group 8
'tests/Integration/Commands/Repair-SqlDscPowerBIReportServer.Integration.Tests.ps1'
# Group 9
Expand Down
102 changes: 102 additions & 0 deletions source/Private/Get-HResultMessage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<#
.SYNOPSIS
Gets a human-readable message for a given HRESULT code.

.DESCRIPTION
Translates common Windows HRESULT error codes into human-readable
messages. This is particularly useful when CIM methods return an
HRESULT code without detailed error information in ExtendedErrors
or Error properties.

.PARAMETER HResult
The HRESULT code to translate. This is typically a 32-bit signed
integer returned from a Windows API or CIM method call.

.OUTPUTS
`System.String`

Returns a descriptive message for known HRESULT codes, or a generic
message with the hexadecimal code for unknown values.

.EXAMPLE
Get-HResultMessage -HResult -2147023181

Returns: The account has not been granted the requested logon type at
this computer. Verify that the service account has the required
permissions to interact with the Reporting Services WMI provider.

.EXAMPLE
Get-HResultMessage -HResult -2147024891

Returns: Access is denied. Verify that the current user has administrator
rights on the Reporting Services instance.

.NOTES
This function is used internally by other commands to provide actionable
error messages when Reporting Services CIM methods fail without detailed
error information. These codes have not been verified against any official
Microsoft documentation, and based on the common HRESULT values in
https://learn.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values.
#>
function Get-HResultMessage
{
[CmdletBinding()]
[OutputType([System.String])]
param
(
[Parameter(Mandatory = $true)]
[System.Int32]
$HResult
)

<#
HRESULT values are 32-bit signed integers. Negative values indicate
errors. The HRESULT is composed of:
- Bit 31: Severity (0 = success, 1 = error)
- Bits 16-30: Facility code
- Bits 0-15: Error code

Common HRESULT values are documented at:
https://learn.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values
#>
$hResultMessages = @{
# cSpell: ignore ACCESSDENIED LOGON
# E_ACCESSDENIED (0x80070005) - General access denied error
-2147024891 = $script:localizedData.HResult_AccessDenied

# ERROR_LOGON_TYPE_NOT_GRANTED (0x80070533) - Account lacks logon rights
-2147023181 = $script:localizedData.HResult_LogonTypeNotGranted

# E_FAIL (0x80004005) - Unspecified failure
-2147467259 = $script:localizedData.HResult_UnspecifiedFailure

# E_INVALIDARG (0x80070057) - One or more arguments are invalid
-2147024809 = $script:localizedData.HResult_InvalidArgument

# E_OUTOFMEMORY (0x8007000E) - Out of memory
-2147024882 = $script:localizedData.HResult_OutOfMemory

# RPC_E_DISCONNECTED (0x80010108) - The object invoked has disconnected
-2147417848 = $script:localizedData.HResult_RpcDisconnected

# RPC_S_SERVER_UNAVAILABLE (0x800706BA) - The RPC server is unavailable
-2147023174 = $script:localizedData.HResult_RpcServerUnavailable

# ERROR_SERVICE_NOT_ACTIVE (0x80070426) - The service has not been started
-2147023834 = $script:localizedData.HResult_ServiceNotActive
}

if ($hResultMessages.ContainsKey($HResult))
{
return $hResultMessages[$HResult]
}

<#
Return a generic message with the hexadecimal representation for unknown codes.
Convert to hex using bitwise operation to handle negative values that would
overflow when casting directly to UInt32 (e.g., Int32.MinValue = -2147483648).
#>
$hexValue = '0x{0:X8}' -f ($HResult -band 0xFFFFFFFF)

return ($script:localizedData.HResult_Unknown -f $hexValue)
}
32 changes: 23 additions & 9 deletions source/Private/Invoke-RsCimMethod.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,34 @@ function Invoke-RsCimMethod
#>
if ($invokeCimMethodResult -and $invokeCimMethodResult.HRESULT -ne 0)
{
if ($invokeCimMethodResult | Get-Member -Name 'ExtendedErrors')
$errorDetails = $null

<#
The returned object property ExtendedErrors is an array
so that needs to be concatenated. Check if it has actual
content before using it.
#>
if (($invokeCimMethodResult | Get-Member -Name 'ExtendedErrors') -and $invokeCimMethodResult.ExtendedErrors)
{
<#
The returned object property ExtendedErrors is an array
so that needs to be concatenated.
#>
$errorMessage = $invokeCimMethodResult.ExtendedErrors -join ';'
$errorDetails = $invokeCimMethodResult.ExtendedErrors -join ';'
}
else

# Fall back to Error property if ExtendedErrors was empty or not present.
if (-not $errorDetails -and ($invokeCimMethodResult | Get-Member -Name 'Error') -and $invokeCimMethodResult.Error)
{
$errorMessage = $invokeCimMethodResult.Error
$errorDetails = $invokeCimMethodResult.Error
}

$errorMessage = $script:localizedData.Invoke_RsCimMethod_FailedToInvokeMethod -f $MethodName, $errorMessage, $invokeCimMethodResult.HRESULT
# Use a fallback message if neither property had content.
if (-not $errorDetails)
{
$errorDetails = $script:localizedData.Invoke_RsCimMethod_NoErrorDetails
}

# Try to translate the HRESULT code into a human-readable message.
$hResultMessage = Get-HResultMessage -HResult $invokeCimMethodResult.HRESULT

$errorMessage = $script:localizedData.Invoke_RsCimMethod_FailedToInvokeMethod -f $MethodName, $errorDetails, $hResultMessage, $invokeCimMethodResult.HRESULT

throw $errorMessage
}
Expand Down
2 changes: 0 additions & 2 deletions source/Public/Deny-SqlDscServerPermission.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,13 @@
.EXAMPLE
$serverInstance = Connect-SqlDscDatabaseEngine
$login = $serverInstance | Get-SqlDscLogin -Name 'MyLogin'

Deny-SqlDscServerPermission -Login $login -Permission ConnectSql, ViewServerState

Denies the specified permissions to the login 'MyLogin'.

.EXAMPLE
$serverInstance = Connect-SqlDscDatabaseEngine
$role = $serverInstance | Get-SqlDscRole -Name 'MyRole'

$role | Deny-SqlDscServerPermission -Permission AlterAnyDatabase -Force

Denies the specified permissions to the role 'MyRole' without prompting for confirmation.
Expand Down
3 changes: 0 additions & 3 deletions source/Public/Get-SqlDscServerPermission.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,19 @@
.EXAMPLE
$serverInstance = Connect-SqlDscDatabaseEngine
$login = $serverInstance | Get-SqlDscLogin -Name 'MyLogin'

Get-SqlDscServerPermission -Login $login

Get the permissions for the login 'MyLogin' using a Login object.

.EXAMPLE
$serverInstance = Connect-SqlDscDatabaseEngine
$role = $serverInstance | Get-SqlDscRole -Name 'MyRole'

$role | Get-SqlDscServerPermission

Get the permissions for the server role 'MyRole' using a ServerRole object from the pipeline.

.EXAMPLE
$serverInstance = Connect-SqlDscDatabaseEngine

$serverInstance | Get-SqlDscLogin | Get-SqlDscServerPermission

Get the permissions for all logins from the pipeline.
Expand Down
3 changes: 0 additions & 3 deletions source/Public/Grant-SqlDscServerPermission.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,19 @@
.EXAMPLE
$serverInstance = Connect-SqlDscDatabaseEngine
$login = $serverInstance | Get-SqlDscLogin -Name 'MyLogin'

Grant-SqlDscServerPermission -Login $login -Permission ConnectSql, ViewServerState

Grants the specified permissions to the login 'MyLogin'.

.EXAMPLE
$serverInstance = Connect-SqlDscDatabaseEngine
$role = $serverInstance | Get-SqlDscRole -Name 'MyRole'

$role | Grant-SqlDscServerPermission -Permission AlterAnyDatabase -WithGrant -Force

Grants the specified permissions with grant option to the role 'MyRole' without prompting for confirmation.

.EXAMPLE
$serverInstance = Connect-SqlDscDatabaseEngine

$serverInstance | Get-SqlDscLogin | Grant-SqlDscServerPermission -Permission ConnectSql

Grants ConnectSql permission to all logins from the pipeline.
Expand Down
3 changes: 0 additions & 3 deletions source/Public/New-SqlDscDatabase.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,10 @@

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'

$primaryFile = New-SqlDscDataFile -Name 'MyDatabase_Primary' -FileName 'D:\SQLData\MyDatabase.mdf' -Size 102400 -Growth 10240 -GrowthType 'KB' -IsPrimaryFile -AsSpec
$primaryFileGroup = New-SqlDscFileGroup -Name 'PRIMARY' -Files @($primaryFile) -IsDefault $true -AsSpec

$secondaryFile = New-SqlDscDataFile -Name 'MyDatabase_Secondary' -FileName 'E:\SQLData\MyDatabase.ndf' -Size 204800 -AsSpec
$secondaryFileGroup = New-SqlDscFileGroup -Name 'SECONDARY' -Files @($secondaryFile) -AsSpec

$serverObject | New-SqlDscDatabase -Name 'MyDatabase' -FileGroup @($primaryFileGroup, $secondaryFileGroup) -Force

Creates a new database named **MyDatabase** with custom PRIMARY and SECONDARY file groups
Expand Down
2 changes: 0 additions & 2 deletions source/Public/New-SqlDscDatabaseSnapshot.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@
.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
$sourceDb = $serverObject.Databases['MyDatabase']

$dataFile = New-SqlDscDataFile -Name 'MyDatabase_Data' -FileName 'C:\Snapshots\MyDatabase_Data.ss' -AsSpec
$fileGroup = New-SqlDscFileGroup -Name 'PRIMARY' -Files @($dataFile) -AsSpec

$serverObject | New-SqlDscDatabaseSnapshot -Name 'MyDB_Snap' -DatabaseName 'MyDatabase' -FileGroup @($fileGroup) -Force

Creates a new database snapshot named **MyDB_Snap** from the source database
Expand Down
Loading