Skip to content

Commit a9cc3a3

Browse files
authored
New resource: xRDConnectionBrokerHAMode (#110)
1 parent 42739cd commit a9cc3a3

8 files changed

Lines changed: 301 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
55

66
## [Unreleased]
77

8+
### Added
9+
10+
- xRDConnectionBrokerHAMode
11+
- New resource to configure HA mode on a connection broker
12+
813
## [2.1.0] - 2022-08-07
914

1015
### Added

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,11 @@ The resource examples are also available in the [xRemoteDesktopSessionHost Wiki]
139139
* **ConnectionBroker**: Specifies the Remote Desktop Connection Broker (RD Connection Broker) server for a Remote Desktop deployment.
140140
* **ImportPath**: The certificate that should be used, should point to a PFX file on the filesystem.
141141
* **Credential**: The password (if applicable) for the PFX file. The username is ignored.
142+
143+
### xRDConnectionBrokerHAMode
144+
145+
* **ConnectionBroker**: Specifies the Remote Desktop Connection Broker (RD Connection Broker) server for a Remote Desktop deployment.
146+
* **DatabaseConnectionString**: Specifies the primary connection string to the database.
147+
* **DatabaseSecondaryConnectionString**: Specifies the secondary connection string to the database.
148+
* **DatabaseFilePath**: Specifies the database file path of SQL Server.
149+
* **ClientAccessName**: Specifies the FQDN of client access name.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
Import-Module -Name "$PSScriptRoot\..\..\Modules\xRemoteDesktopSessionHostCommon.psm1"
2+
if (!(Test-xRemoteDesktopSessionHostOsRequirement))
3+
{
4+
throw "The minimum OS requirement was not met."
5+
}
6+
Import-Module -Name RemoteDesktop
7+
$localhost = [System.Net.Dns]::GetHostByName((hostname)).HostName
8+
9+
#######################################################################
10+
# The Get-TargetResource cmdlet.
11+
#######################################################################
12+
function Get-TargetResource
13+
{
14+
[CmdletBinding()]
15+
[OutputType([System.Collections.Hashtable])]
16+
param
17+
(
18+
[Parameter()]
19+
[string] $ConnectionBroker,
20+
21+
[Parameter(Mandatory = $true)]
22+
[string] $DatabaseConnectionString,
23+
24+
[Parameter()]
25+
[string] $DatabaseSecondaryConnectionString,
26+
27+
[Parameter()]
28+
[string] $DatabaseFilePath,
29+
30+
[Parameter(Mandatory = $true)]
31+
[ValidateLength(1, 256)]
32+
[string] $ClientAccessName
33+
)
34+
Write-Verbose -Message ($script:localizedData.VerboseGetHAMode -f $ConnectionBroker, $ClientAccessName)
35+
36+
if ([string]::IsNullOrWhiteSpace($ConnectionBroker))
37+
{
38+
$ConnectionBroker = $localhost
39+
}
40+
41+
$ConnectionBrokerHighAvailability = Get-RDConnectionBrokerHighAvailability -ConnectionBroker $ConnectionBroker -ErrorAction SilentlyContinue
42+
43+
@{
44+
ConnectionBroker = $ConnectionBrokerHighAvailability.ConnectionBroker
45+
ActiveManagementServer = $ConnectionBrokerHighAvailability.ActiveManagementServer
46+
ClientAccessName = $ConnectionBrokerHighAvailability.ClientAccessName
47+
DatabaseConnectionString = $ConnectionBrokerHighAvailability.DatabaseConnectionString
48+
DatabaseSecondaryConnectionString = $DatabaseSecondaryConnectionString
49+
DatabaseFilePath = $ConnectionBrokerHighAvailability.DatabaseFilePath
50+
}
51+
52+
}
53+
54+
55+
########################################################################
56+
# The Set-TargetResource cmdlet.
57+
########################################################################
58+
function Set-TargetResource
59+
60+
{
61+
[CmdletBinding()]
62+
param
63+
(
64+
[Parameter()]
65+
[string] $ConnectionBroker,
66+
67+
[Parameter(Mandatory = $true)]
68+
[string] $DatabaseConnectionString,
69+
70+
[Parameter()]
71+
[string] $DatabaseSecondaryConnectionString,
72+
73+
[Parameter()]
74+
[string] $DatabaseFilePath,
75+
76+
[Parameter(Mandatory = $true)]
77+
[ValidateLength(1, 256)]
78+
[string] $ClientAccessName
79+
)
80+
81+
Write-Verbose -Message ($script:localizedData.VerboseConfigureHAMode -f $ConnectionBroker, $ClientAccessName)
82+
83+
if ([string]::IsNullOrWhiteSpace($ConnectionBroker))
84+
{
85+
$ConnectionBroker = $localhost
86+
}
87+
88+
$parameters = @{
89+
ConnectionBroker = $ConnectionBroker
90+
DatabaseConnectionString = $DatabaseConnectionString
91+
ClientAccessName = $ClientAccessName
92+
}
93+
94+
if (-not [string]::IsNullOrWhiteSpace($DatabaseFilePath))
95+
{
96+
$parameters['DatabaseFilePath'] = $DatabaseFilePath
97+
}
98+
99+
if (-not [string]::IsNullOrWhiteSpace($DatabaseSecondaryConnectionString))
100+
{
101+
$parameters['DatabaseSecondaryConnectionString'] = $DatabaseSecondaryConnectionString
102+
}
103+
104+
Set-RDConnectionBrokerHighAvailability @parameters
105+
}
106+
107+
108+
#######################################################################
109+
# The Test-TargetResource cmdlet.
110+
#######################################################################
111+
function Test-TargetResource
112+
{
113+
[CmdletBinding()]
114+
[OutputType([System.Boolean])]
115+
param
116+
(
117+
[Parameter()]
118+
[string] $ConnectionBroker,
119+
120+
[Parameter(Mandatory = $true)]
121+
[string] $DatabaseConnectionString,
122+
123+
[Parameter()]
124+
[string] $DatabaseSecondaryConnectionString,
125+
126+
[Parameter()]
127+
[string] $DatabaseFilePath,
128+
129+
[Parameter(Mandatory = $true)]
130+
[ValidateLength(1, 256)]
131+
[string] $ClientAccessName
132+
)
133+
Write-Verbose ($script:localizedData.VerboseTestHAMode -f $ConnectionBroker, $ClientAccessName)
134+
135+
if ([string]::IsNullOrWhiteSpace($ConnectionBroker))
136+
{
137+
$PSBoundParameters['ConnectionBroker'] = $localhost
138+
}
139+
140+
-not [string]::IsNullOrWhiteSpace((Get-TargetResource @PSBoundParameters).ActiveManagementServer)
141+
}
142+
143+
Export-ModuleMember -Function *-TargetResource
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
[ClassVersion("1.0.0.0"), FriendlyName("xRDConnectionBrokerHAMode")]
3+
class MSFT_xRDConnectionBrokerHAMode : OMI_BaseResource
4+
{
5+
[Key, Description("Specifies the FQDN of client access name.")] string ClientAccessName;
6+
[write, required, Description("Specifies the primary connection string to the database.")] string DatabaseConnectionString;
7+
[write, Description("Specifies the secondary connection string to the database.")] string DatabaseSecondaryConnectionString;
8+
[write, Description("Specifies the FQDN of a server to host the RD Connection Broker role service.")] string ConnectionBroker;
9+
[write, Description("Specifies the database file path of SQL Server.")] string DatabaseFilePath;
10+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Localized resources for MSFT_xRDCertificateConfiguration
2+
3+
ConvertFrom-StringData @'
4+
VerboseConfigureHAMode = Set RD Connection Broker {0} for high availability mode using Client Access name {1}.
5+
VerboseGetHAMode = Getting information about Connection Broker {0} for high availability mode using Client Access name {1}.
6+
VerboseTestHAMode = Testing existing HA configuration for Connection Broker {0} using Client Access name {1}.
7+
'@
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<#
2+
.DESCRIPTION
3+
This example shows how to configure HA mode on a connection broker.
4+
#>
5+
6+
Configuration Example
7+
{
8+
Import-DscResource -ModuleName 'xRemoteDesktopSessionHost'
9+
10+
Node localhost {
11+
12+
xRDConnectionBrokerHAMode MyGateway {
13+
ConnectionBroker = 'RDCB1'
14+
DatabaseConnectionString = 'DRIVER=SQL Server Native Client 11.0;SERVER=RDDB1;Trusted_Connection=Yes;APP=Remote Desktop Services Connection Broker;Database=RDS'
15+
ClientAccessName = 'rdsfarm.contoso.com'
16+
}
17+
}
18+
}

source/xRemoteDesktopSessionHost.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
'xRDSessionCollection'
4040
'xRDSessionCollectionConfiguration'
4141
'xRDsessionDeployment'
42+
'xRDConnectionBrokerHAMode'
4243
)
4344

4445
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
$script:DSCModuleName = 'xRemoteDesktopSessionHost'
2+
$script:DSCResourceName = 'MSFT_xRDConnectionBrokerHAMode'
3+
4+
#region HEADER
5+
6+
function Invoke-TestSetup
7+
{
8+
try
9+
{
10+
Import-Module -Name DscResource.Test -Force
11+
}
12+
catch [System.IO.FileNotFoundException]
13+
{
14+
throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.'
15+
}
16+
17+
$script:testEnvironment = Initialize-TestEnvironment `
18+
-DSCModuleName $script:dscModuleName `
19+
-DSCResourceName $script:dscResourceName `
20+
-ResourceType 'Mof' `
21+
-TestType 'Unit'
22+
}
23+
24+
function Invoke-TestCleanup
25+
{
26+
Restore-TestEnvironment -TestEnvironment $script:testEnvironment
27+
}
28+
29+
Invoke-TestSetup
30+
31+
try
32+
{
33+
InModuleScope $script:dscResourceName {
34+
$script:DSCResourceName = 'MSFT_xRDConnectionBrokerHAMode'
35+
36+
#region Function Get-TargetResource
37+
Describe "Testing $($script:DSCResourceName)" {
38+
Mock -CommandName Import-Module -MockWith {} -ParameterFilter { $Name -eq 'RemoteDesktop' }
39+
40+
Mock -CommandName Set-RDConnectionBrokerHighAvailability -ParameterFilter { $ClientAccessName -eq 'rdsfarm.contoso.com' }
41+
42+
Context 'Connection Broker not in HA mode' {
43+
44+
Mock -CommandName Get-RDConnectionBrokerHighAvailability -MockWith {
45+
[pscustomobject]@{
46+
ConnectionBroker = 'RDCB1'
47+
ActiveManagementServer = ''
48+
ClientAccessName = ''
49+
DatabaseConnectionString = 'DRIVER=SQL Server Native Client 11.0;SERVER=RDDB1;Trusted_Connection=Yes;APP=Remote Desktop Services Connection Broker;Database=RDS'
50+
}
51+
}
52+
53+
$resourceNotConfiguredSplat = @{
54+
DatabaseConnectionString = 'DRIVER=SQL Server Native Client 11.0;SERVER=RDDB1;Trusted_Connection=Yes;APP=Remote Desktop Services Connection Broker;Database=RDS'
55+
DatabaseSecondaryConnectionString = 'DRIVER=SQL Server Native Client 11.0;SERVER=RDDB1.contoso.com;Trusted_Connection=Yes;APP=Remote Desktop Services Connection Broker;Database=RDS'
56+
ClientAccessName = 'rdsfarm.contoso.com'
57+
DatabaseFilePath = 'C:\RDFiles\RemoteDesktopDeployment.mdf'
58+
}
59+
60+
It 'Get-TargetResource returns no active management server' {
61+
(Get-TargetResource @resourceNotConfiguredSplat).ActiveManagementServer | Should -BeNullOrEmpty
62+
}
63+
64+
It 'Test-TargetResource returns false' {
65+
Test-TargetResource @resourceNotConfiguredSplat | Should -BeFalse
66+
}
67+
68+
It 'Set-TargetResource runs Set-RDConnectionBrokerHighAvailability' {
69+
Set-TargetResource @resourceNotConfiguredSplat
70+
Assert-MockCalled -CommandName Set-RDConnectionBrokerHighAvailability -Times 1 -Exactly -ParameterFilter {
71+
$DatabaseConnectionString -eq 'DRIVER=SQL Server Native Client 11.0;SERVER=RDDB1;Trusted_Connection=Yes;APP=Remote Desktop Services Connection Broker;Database=RDS' -and
72+
$ClientAccessName -eq 'rdsfarm.contoso.com'
73+
}
74+
}
75+
}
76+
77+
Context 'Connection Broker in HA mode' {
78+
79+
Mock -CommandName Get-RDConnectionBrokerHighAvailability -MockWith {
80+
[pscustomobject]@{
81+
ConnectionBroker = 'RDCB1'
82+
ActiveManagementServer = 'RDCB1'
83+
ClientAccessName = 'rdsfarm.contoso.com'
84+
DatabaseConnectionString = 'DRIVER=SQL Server Native Client 11.0;SERVER=RDDB1;Trusted_Connection=Yes;APP=Remote Desktop Services Connection Broker;Database=RDS'
85+
}
86+
}
87+
88+
$resourceConfiguredSplat = @{
89+
DatabaseConnectionString = 'DRIVER=SQL Server Native Client 11.0;SERVER=RDDB1;Trusted_Connection=Yes;APP=Remote Desktop Services Connection Broker;Database=RDS'
90+
ClientAccessName = 'rdsfarm.contoso.com'
91+
}
92+
93+
It 'Get-TargetResource returns an active management server' {
94+
(Get-TargetResource @resourceConfiguredSplat).ActiveManagementServer | Should -Be 'RDCB1'
95+
}
96+
97+
It 'Test-TargetResource returns true' {
98+
Test-TargetResource @resourceConfiguredSplat | Should -BeTrue
99+
}
100+
}
101+
}
102+
}
103+
}
104+
finally
105+
{
106+
#region FOOTER
107+
Invoke-TestCleanup
108+
#endregion
109+
}

0 commit comments

Comments
 (0)