Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

ADReadOnlyDomainControllerAccount: New resource #713

Merged
merged 34 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
17b00f3
Add ADReadOnlyDomainControllerAccount resource
Borgquite Jul 29, 2024
c290927
Remove InstallDns check and just pass through (can't be run against R…
Borgquite Jul 29, 2024
48364b5
Update comment
Borgquite Jul 29, 2024
988f199
Pin GitVersion to 5.x
Borgquite Jul 29, 2024
e47440d
SiteName field required for RODCs, but not included in Get-TargetReso…
Borgquite Jul 29, 2024
a6ceac8
Remove unnecessary registry checks
Borgquite Jul 29, 2024
d5a8ed4
Add tests
Borgquite Jul 29, 2024
eb9e9f8
Remove unnecessary test
Borgquite Jul 29, 2024
c8cdbb2
Fix error message when no RODC account available
Borgquite Jul 29, 2024
f463eb2
SiteName now required - add to Get-TargetResource calls
Borgquite Jul 29, 2024
5ebe13e
More test changes because SiteName is required
Borgquite Jul 29, 2024
8e6880e
Need to specify SiteName specifically
Borgquite Jul 30, 2024
1842d5f
Remove duplicated test, update name
Borgquite Jul 30, 2024
ba191fe
Fix a couple more SiteName tests
Borgquite Jul 30, 2024
55d1542
ADDomainController: Add UseExistingAccount parameter
Borgquite Jul 30, 2024
7eb7331
Can't call Install-ADDSDomainController with UseExistingAccount and S…
Borgquite Jul 30, 2024
dc53723
Fix test - UseExistingAccount and ReadOnlyReplica are mutually exclusive
Borgquite Jul 30, 2024
6df2fb3
Update README
Borgquite Jul 30, 2024
1f3a69e
Get-DomainControllerObject - only test if this computer is a domain c…
Borgquite Jul 30, 2024
e660790
Update example
Borgquite Jul 30, 2024
3102b70
Update example
Borgquite Jul 30, 2024
7d26fdd
Typo
Borgquite Jul 30, 2024
06455ae
Corrected example
Borgquite Jul 30, 2024
d70604a
Update test to make it clearer what we're doing
Borgquite Aug 9, 2024
b0f2262
Updated CHANGELOG.md
Borgquite Aug 12, 2024
d4b41dd
Update help to remove references to cmdlet
Borgquite Aug 12, 2024
1a2bbb8
Bring lines within length, update synopsis
Borgquite Aug 12, 2024
8630a20
Bring line within length, update synopsis
Borgquite Aug 12, 2024
b7a94fa
Minor fixes
Borgquite Aug 12, 2024
c8b394f
Tweak test names
Borgquite Aug 12, 2024
3d34f80
Add test for Get-DomainControllerObject when running locally
Borgquite Aug 12, 2024
05e1958
Fix test
Borgquite Aug 12, 2024
2815691
Update doco
Borgquite Aug 12, 2024
08e2163
Basic integration test
Borgquite Aug 14, 2024
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
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ For older change log history see the [historic changelog](HISTORIC_CHANGELOG.md)

## [Unreleased]

### Added

- ADDomainController
- New parameter UseExistingAccount for attaching a server to an existing RODC account.
([issue #711](https://github.com/dsccommunity/ActiveDirectoryDsc/issues/711)).
- ADReadOnlyDomainControllerAccount
- New resource for pre-creating Read Only Domain Controller accounts.
([issue #40](https://github.com/dsccommunity/ActiveDirectoryDsc/issues/40))
([issue #711](https://github.com/dsccommunity/ActiveDirectoryDsc/issues/711)).

### Fixed

- ActiveDirectoryDsc.Common
- Fixed Get-DomainControllerObject to allow checking non-local domain controller accounts.
- Update build process to pin GitVersion to 5.* to resolve errors
(https://github.com/gaelcolas/Sampler/issues/477).

## [6.5.0] - 2024-05-17

### Added
Expand Down
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ stages:
vmImage: 'windows-latest'
steps:
- pwsh: |
dotnet tool install --global GitVersion.Tool
dotnet tool install --global GitVersion.Tool --version 5.*
$gitVersionObject = dotnet-gitversion | ConvertFrom-Json
$gitVersionObject.PSObject.Properties.ForEach{
Write-Host -Object "Setting Task Variable '$($_.Name)' with value '$($_.Value)'."
Expand Down
1 change: 1 addition & 0 deletions source/ActiveDirectoryDsc.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ DscResourcesToExport = @(
'ADObjectPermissionEntry'
'ADOptionalFeature'
'ADOrganizationalUnit'
'ADReadOnlyDomainControllerAccount'
'ADReplicationSite'
'ADReplicationSiteLink'
'ADServicePrincipalName'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US'
.PARAMETER SafemodeAdministratorPassword
Provide a password that will be used to set the DSRM password. This is a PSCredential.

.PARAMETER UseExistingAccount
Specifies whether to use an existing read only domain controller account.

Not used in Get-TargetResource.

.NOTES
Used Functions:
Name | Module
Expand All @@ -50,7 +55,11 @@ function Get-TargetResource

[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SafemodeAdministratorPassword
$SafemodeAdministratorPassword,

[Parameter()]
[System.Boolean]
$UseExistingAccount
)

Assert-Module -ModuleName 'ActiveDirectory'
Expand Down Expand Up @@ -79,11 +88,13 @@ function Get-TargetResource
$delegateAdministratorAccountName = $null
if ($domainControllerObject.IsReadOnly)
{
$domainControllerComputerObject = $domainControllerObject.ComputerObjectDN | Get-ADComputer -Properties ManagedBy -Credential $Credential
$domainControllerComputerObject = $domainControllerObject.ComputerObjectDN |
Get-ADComputer -Properties ManagedBy -Credential $Credential
if ($domainControllerComputerObject.ManagedBy)
{
$domainControllerManagedByObject = $domainControllerComputerObject.ManagedBy | Get-ADObject -Properties objectSid -Credential $Credential

$domainControllerManagedByObject = $domainControllerComputerObject.ManagedBy |
Get-ADObject -Properties objectSid -Credential $Credential

$delegateAdministratorAccountName = Resolve-SamAccountName -ObjectSid $domainControllerManagedByObject.objectSid
}
}
Expand Down Expand Up @@ -115,6 +126,7 @@ function Get-TargetResource
SafemodeAdministratorPassword = $SafemodeAdministratorPassword
SiteName = $domainControllerObject.Site
SysvolPath = $serviceNETLOGON.SysVol -replace '\\sysvol$', ''
UseExistingAccount = $UseExistingAccount
}
}
else
Expand All @@ -138,6 +150,7 @@ function Get-TargetResource
SafemodeAdministratorPassword = $SafemodeAdministratorPassword
SiteName = $null
SysvolPath = $null
UseExistingAccount = $UseExistingAccount
}
}

Expand Down Expand Up @@ -202,6 +215,10 @@ function Get-TargetResource
The parameter `InstallDns` is only used during the provisioning of a domain
controller. The parameter cannot be used to install or uninstall the DNS
server on an already provisioned domain controller.

.PARAMETER UseExistingAccount
Specifies whether to use an existing read only domain controller account.

.NOTES
Used Functions:
Name | Module
Expand Down Expand Up @@ -289,7 +306,11 @@ function Set-TargetResource

[Parameter()]
[System.Boolean]
$InstallDns
$InstallDns,

[Parameter()]
[System.Boolean]
$UseExistingAccount
)

$getTargetResourceParameters = @{
Expand Down Expand Up @@ -395,6 +416,11 @@ function Set-TargetResource
$installADDSDomainControllerParameters.Add('InstallDns', $InstallDns)
}

if ($PSBoundParameters.ContainsKey('UseExistingAccount'))
{
$installADDSDomainControllerParameters.Add('UseExistingAccount', $UseExistingAccount)
}

if (-not [System.String]::IsNullOrWhiteSpace($InstallationMediaPath))
{
$installADDSDomainControllerParameters.Add('InstallationMediaPath', $InstallationMediaPath)
Expand Down Expand Up @@ -464,7 +490,8 @@ function Set-TargetResource

$delegateAdministratorAccountSecurityIdentifier = Resolve-SecurityIdentifier -SamAccountName $DelegatedAdministratorAccountName

Set-ADComputer -Identity $domainControllerObject.ComputerObjectDN -ManagedBy $delegateAdministratorAccountSecurityIdentifier -Credential $Credential
Set-ADComputer -Identity $domainControllerObject.ComputerObjectDN `
-ManagedBy $delegateAdministratorAccountSecurityIdentifier -Credential $Credential
}
}

Expand Down Expand Up @@ -671,6 +698,11 @@ function Set-TargetResource

Not used in Test-TargetResource.

.PARAMETER UseExistingAccount
Specifies whether to use an existing read only domain controller account.

Not used in Test-TargetResource.

.NOTES
Used Functions:
Name | Module
Expand Down Expand Up @@ -747,7 +779,11 @@ function Test-TargetResource

[Parameter()]
[System.Boolean]
$InstallDns
$InstallDns,

[Parameter()]
[System.Boolean]
$UseExistingAccount
)

Write-Verbose -Message ($script:localizedData.TestingConfiguration -f $env:COMPUTERNAME, $DomainName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ class MSFT_ADDomainController : OMI_BaseResource
[Write, Description("The path of the media you want to use install the Domain Controller.")] String InstallationMediaPath;
[Write, Description("Specifies if the domain controller will be a Global Catalog (GC).")] Boolean IsGlobalCatalog;
[Read, Description("Returns the state of the Domain Controller.")] String Ensure;
[Write, Description("Indicates that the cmdlet installs the domain controller as an Read-Only Domain Controller (RODC) for an existing domain.")] Boolean ReadOnlyReplica;
[Write, Description("Indicates that the resource installs the domain controller as an Read-Only Domain Controller (RODC) for an existing domain.")] Boolean ReadOnlyReplica;
[Write, Description("Specifies the user or group that is the delegated administrator of this Read-Only Domain Controller (RODC).")] String DelegatedAdministratorAccountName;
[Write, Description("Specifies an array of names of user accounts, group accounts, and computer accounts whose passwords can be replicated to this Read-Only Domain Controller (RODC).")] String AllowPasswordReplicationAccountName[];
[Write, Description("Specifies the names of user accounts, group accounts, and computer accounts whose passwords are not to be replicated to this Read-Only Domain Controller (RODC).")] String DenyPasswordReplicationAccountName[];
[Write, Description("Specifies one or more Flexible Single Master Operation (FSMO) roles to move to this domain controller. The current owner must be online and responding for the move to be allowed."), ValueMap{"DomainNamingMaster", "SchemaMaster", "InfrastructureMaster", "PDCEmulator", "RIDMaster"}, Values{"DomainNamingMaster", "SchemaMaster", "InfrastructureMaster", "PDCEmulator", "RIDMaster"}] String FlexibleSingleMasterOperationRole[];
[Write, Description("Specifies if the DNS Server service should be installed and configured on the Domain Controller. If this is not set the default value of the parameter `InstallDns` of the cmdlet Install-ADDSDomainController is used. This parameter is only used during the provisioning of a domain controller. The parameter cannot be used to install or uninstall the DNS server on an already provisioned domain controller.")] Boolean InstallDns;
[Write, Description("Indicates that the resource attaches a server to an existing Read-Only Domain Controller (RODC) account. If specified, a member of the Domain Admins group or a delegated user can apply this resource.")] Boolean UseExistingAccount;
};
18 changes: 9 additions & 9 deletions source/DSCResources/MSFT_ADDomainController/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ is used. The parameter `InstallDns` is only used during the provisioning
of a domain controller. The parameter cannot be used to install or uninstall
the DNS server on an already provisioned domain controller.

>**Note:** If the account used for the parameter `Credential`
>cannot connect to another domain controller, for example using a credential
>without the domain name, then the cmdlet `Install-ADDSDomainController` will
>seemingly halt (without reporting an error) when trying to replicate
>information from another domain controller.
>Make sure to use a correct domain account with the correct permission as
>the account for the parameter `Credential`.
> **Note:** If the account used for the parameter `Credential`
> cannot connect to another domain controller, for example using a credential
> without the domain name, then the cmdlet `Install-ADDSDomainController` will
> seemingly halt (without reporting an error) when trying to replicate
> information from another domain controller.
> Make sure to use a correct domain account with the correct permission as
> the account for the parameter `Credential`.

The parameter `FlexibleSingleMasterOperationRole` is ignored until
the node has been provisioned as a domain controller. Take extra care
to make sure the Flexible Single Master Operation (FSMO) roles are moved
accordingly to avoid that two domain controller try to get to be the
owner of the same role (potential "ping-pong"-behavior).

>The resource does not support seizing of Flexible Single Master Operation
>(FSMO) roles
> The resource does not support seizing of Flexible Single Master Operation
> (FSMO) roles

## Requirements

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ConvertFrom-StringData @'
ResolveDomainName = Resolving the domain name '{0}'. (ADDC0001)
DomainPresent = The domain '{0}' is present. Looking for domain controllers. (ADDC0002)
DomainPresent = The domain '{0}' is present. Looking for domain controller. (ADDC0002)
NotDomainController = The current node '{0}' is not a domain controller. (ADDC0006)
IsDomainController = The current node '{0}' is a domain controller for the domain '{1}'. (ADDC0007)
MissingDomain = Current node could not find the domain '{0}'. (ADDC0008)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
Write - Boolean
Specifies if the DNS Server service should be installed and configured on the Domain Controller. If this is not set the default value of the parameter `InstallDns` of the cmdlet Install-ADDSDomainController is used. This parameter is only used during the provisioning of a domain controller. The parameter cannot be used to install or uninstall the DNS server on an already provisioned domain controller.

.PARAMETER UseExistingAccount
Write - Boolean
Indicates that the cmdlet attaches a server to an existing Read-Only Domain Controller (RODC) account. If specified, a member of the Domain Admins group or a delegated user can run this cmdlet.

.EXAMPLE 1

This configuration will add a domain controller to the domain
Expand Down Expand Up @@ -284,7 +288,7 @@ Configuration ADDomainController_AddDomainControllerToDomainUsingIFM_Config
.EXAMPLE 4

This configuration will add a read-only domain controller to the domain contoso.com
and specify a list of account, whose passwords are allowed/denied for synchronisation.
and specify a list of accounts, whose passwords are allowed/denied for synchronisation.

Configuration ADDomainController_AddReadOnlyDomainController_Config
{
Expand Down Expand Up @@ -346,6 +350,65 @@ Configuration ADDomainController_AddReadOnlyDomainController_Config

.EXAMPLE 5

This configuration will add a read-only domain controller to the domain contoso.com
with a delegated credential, using an existing read only domain controller account.

Configuration ADDomainController_AddReadOnlyDomainControllerExistingAccount_Config
{
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.PSCredential]
$DelegatedCredential,

[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.PSCredential]
$SafeModePassword
)

Import-DscResource -ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName ActiveDirectoryDsc

node localhost
{
WindowsFeature 'InstallADDomainServicesFeature'
{
Ensure = 'Present'
Name = 'AD-Domain-Services'
}

WindowsFeature 'RSATADPowerShell'
{
Ensure = 'Present'
Name = 'RSAT-AD-PowerShell'

DependsOn = '[WindowsFeature]InstallADDomainServicesFeature'
}

WaitForADDomain 'WaitForestAvailability'
{
DomainName = 'contoso.com'
Credential = $DelegatedCredential

DependsOn = '[WindowsFeature]RSATADPowerShell'
}

ADDomainController 'Read-OnlyDomainController(RODC)ExistingAccount'
{
DomainName = 'contoso.com'
Credential = $DelegatedCredential
SafeModeAdministratorPassword = $SafeModePassword
UseExistingAccount = $true

DependsOn = '[WaitForADDomain]WaitForestAvailability'
}
}
}

.EXAMPLE 6

This configuration will add a domain controller to the domain
contoso.com, and when the configuration is enforced it will
move the Flexible Single Master Operation (FSMO) role
Expand Down Expand Up @@ -405,7 +468,7 @@ Configuration ADDomainController_AddDomainControllerAndMoveRole_Config
}
}

.EXAMPLE 6
.EXAMPLE 7

This configuration will add a domain controller to the domain contoso.com
without installing the local DNS server service and using the one in the existing domain.
Expand Down Expand Up @@ -458,5 +521,3 @@ Configuration ADDomainController_AddDomainControllerUsingInstallDns_Config
}
}
}


Loading
Loading