Skip to content

Commit

Permalink
ADReadOnlyDomainControllerAccount: New resource (#713)
Browse files Browse the repository at this point in the history
### Added

- ADDomainController
  - New parameter UseExistingAccount for attaching a server to an existing RODC account (issue #711).
- ADReadOnlyDomainControllerAccount
  - New resource for pre-creating Read Only Domain Controller accounts (issue #40 and issue #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 (issue #477).
  • Loading branch information
Borgquite authored Aug 18, 2024
1 parent f3a3fb6 commit 7c3feec
Show file tree
Hide file tree
Showing 19 changed files with 2,461 additions and 30 deletions.
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 @@ -78,7 +78,7 @@

.PARAMETER ReadOnlyReplica
Write - Boolean
Indicates that the cmdlet installs the domain controller as an Read-Only Domain Controller (RODC) for an existing domain.
Indicates that the resource installs the domain controller as an Read-Only Domain Controller (RODC) for an existing domain.

.PARAMETER DelegatedAdministratorAccountName
Write - String
Expand All @@ -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 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.

.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

0 comments on commit 7c3feec

Please sign in to comment.