Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Computer
- Added `ReuseExistingComputerAccount` parameter to allow reusing an existing
AD computer account when joining a domain instead of deleting and recreating
it. When set to `$true`, the existing account is preserved (SID, group
memberships, GPO links). If no existing account is found, a new one is
created. Default is `$false` -
Fixes [Issue #457](https://github.com/dsccommunity/ComputerManagementDsc/issues/457).

### Changed

- `azure-pipelines.yml`
Expand Down
89 changes: 72 additions & 17 deletions source/DSCResources/DSC_Computer/DSC_Computer.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ $FailToRenameAfterJoinDomainErrorId = 'FailToRenameAfterJoinDomain,Microsoft.Pow

.PARAMETER Options
Specifies advanced options for the Add-Computer join operation.

.PARAMETER ReuseExistingComputerAccount
If $true, the existing computer account in the domain will be reused
instead of being deleted and recreated. This preserves the machine
SID, group memberships, and GPO links. If not specified or $false,
the existing account is deleted and recreated.
#>
function Get-TargetResource
{
Expand Down Expand Up @@ -91,7 +97,11 @@ function Get-TargetResource
[Parameter()]
[ValidateSet('AccountCreate', 'Win9XUpgrade', 'UnsecuredJoin', 'PasswordPass', 'JoinWithNewName', 'JoinReadOnly', 'InstallInvoke')]
[System.String[]]
$Options
$Options,

[Parameter()]
[System.Boolean]
$ReuseExistingComputerAccount
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Write-Verbose -Message ($script:localizedData.GettingComputerStateMessage -f $Name)
Expand All @@ -115,15 +125,16 @@ function Get-TargetResource
-ClientOnly

$returnValue = @{
Name = $env:COMPUTERNAME
DomainName = Get-ComputerDomain
JoinOU = $JoinOU
CurrentOU = Get-ComputerOU
Credential = [ciminstance] $convertToCimCredential
UnjoinCredential = [ciminstance] $convertToCimUnjoinCredential
WorkGroupName = (Get-CimInstance -Class 'Win32_ComputerSystem').Workgroup
Description = (Get-CimInstance -Class 'Win32_OperatingSystem').Description
Server = Get-LogonServer
Name = $env:COMPUTERNAME
DomainName = Get-ComputerDomain
JoinOU = $JoinOU
CurrentOU = Get-ComputerOU
Credential = [ciminstance] $convertToCimCredential
UnjoinCredential = [ciminstance] $convertToCimUnjoinCredential
WorkGroupName = (Get-CimInstance -Class 'Win32_ComputerSystem').Workgroup
Description = (Get-CimInstance -Class 'Win32_OperatingSystem').Description
Server = Get-LogonServer
ReuseExistingComputerAccount = $ReuseExistingComputerAccount
}

return $returnValue
Expand Down Expand Up @@ -160,6 +171,12 @@ function Get-TargetResource

.PARAMETER Options
Specifies advanced options for the Add-Computer join operation.

.PARAMETER ReuseExistingComputerAccount
If $true, the existing computer account in the domain will be reused
instead of being deleted and recreated. This preserves the machine
SID, group memberships, and GPO links. If not specified or $false,
the existing account is deleted and recreated.
#>
function Set-TargetResource
{
Expand Down Expand Up @@ -203,7 +220,11 @@ function Set-TargetResource
[Parameter()]
[ValidateSet('AccountCreate', 'Win9XUpgrade', 'UnsecuredJoin', 'PasswordPass', 'JoinWithNewName', 'JoinReadOnly', 'InstallInvoke')]
[System.String[]]
$Options
$Options,

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

Write-Verbose -Message ($script:localizedData.SettingComputerStateMessage -f $Name)
Expand Down Expand Up @@ -262,13 +283,27 @@ function Set-TargetResource
$addComputerParameters.Add("Server", $Server)
}

# Check for existing computer objecst using ADSI without ActiveDirectory module
# Check for existing computer objects using ADSI without ActiveDirectory module
$computerObject = Get-ADSIComputer -Name $Name -DomainName $DomainName -Credential $Credential

if ($computerObject)
if ($ReuseExistingComputerAccount)
{
if ($computerObject)
{
Write-Verbose -Message ($script:localizedData.ReusingExistingComputerAccount -f $Name, $computerObject.Path)
}
else
{
Write-Verbose -Message ($script:localizedData.NoExistingComputerAccountFound -f $Name)
}
}
else
{
Remove-ADSIObject -Path $computerObject.Path -Credential $Credential
Write-Verbose -Message ($script:localizedData.DeletedExistingComputerObject -f $Name, $computerObject.Path)
if ($computerObject)
{
Remove-ADSIObject -Path $computerObject.Path -Credential $Credential
Write-Verbose -Message ($script:localizedData.DeletedExistingComputerObject -f $Name, $computerObject.Path)
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

if (-not [System.String]::IsNullOrEmpty($Options))
Expand Down Expand Up @@ -458,6 +493,12 @@ function Set-TargetResource

.PARAMETER Options
Specifies advanced options for the Add-Computer join operation.

.PARAMETER ReuseExistingComputerAccount
If $true, the existing computer account in the domain will be reused
instead of being deleted and recreated. This preserves the machine
SID, group memberships, and GPO links. If not specified or $false,
the existing account is deleted and recreated.
#>
function Test-TargetResource
{
Expand Down Expand Up @@ -502,7 +543,11 @@ function Test-TargetResource
[Parameter()]
[ValidateSet('AccountCreate', 'Win9XUpgrade', 'UnsecuredJoin', 'PasswordPass', 'JoinWithNewName', 'JoinReadOnly', 'InstallInvoke')]
[System.String[]]
$Options
$Options,

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

Write-Verbose -Message ($script:localizedData.TestingComputerStateMessage -f $Name)
Expand Down Expand Up @@ -812,6 +857,12 @@ function Remove-ADSIObject

.PARAMETER Options
Specifies advanced options for the Add-Computer join operation.

.PARAMETER ReuseExistingComputerAccount
If $true, the existing computer account in the domain will be reused
instead of being deleted and recreated. This preserves the machine
SID, group memberships, and GPO links. If not specified or $false,
the existing account is deleted and recreated.
#>
function Assert-ResourceProperty
{
Expand Down Expand Up @@ -855,7 +906,11 @@ function Assert-ResourceProperty
[Parameter()]
[ValidateSet('AccountCreate', 'Win9XUpgrade', 'UnsecuredJoin', 'PasswordPass', 'JoinWithNewName', 'JoinReadOnly', 'InstallInvoke')]
[System.String[]]
$Options
$Options,

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

if ($options -contains 'PasswordPass' -and
Expand Down
1 change: 1 addition & 0 deletions source/DSCResources/DSC_Computer/DSC_Computer.schema.mof
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class DSC_Computer : OMI_BaseResource
[Write, Description("The value assigned here will be set as the local computer description.")] String Description;
[Write, Description("The Active Directory Domain Controller to use to join the domain")] String Server;
[Write, Description("Specifies advanced options for the Add-Computer join operation"), ValueMap{"AccountCreate","Win9XUpgrade","UnsecuredJoin","PasswordPass","JoinWithNewName","JoinReadOnly","InstallInvoke"}, Values{"AccountCreate","Win9XUpgrade","UnsecuredJoin","PasswordPass","JoinWithNewName","JoinReadOnly","InstallInvoke"}] String Options[];
[Write, Description("If true, the existing computer account in the domain will be reused instead of being deleted and recreated. This preserves the machine SID, group memberships, and GPO links. Default is false.")] Boolean ReuseExistingComputerAccount;
[Read, Description("A read-only property that specifies the organizational unit that the computer account is currently in.")] String CurrentOU;
};

12 changes: 12 additions & 0 deletions source/DSCResources/DSC_Computer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,15 @@

The resource allows you to configure a computer by changing its name and
description and modifying its Active Directory domain or workgroup membership.

## Parameters

### ReuseExistingComputerAccount

When joining a domain, if a computer account with the same name already exists:

- **Not specified or `$false`** (default): The existing computer account is
deleted and recreated.
- **`$true`**: The existing computer account is reused. This preserves the
machine SID, group memberships, GPO links, and other AD attributes. If no
existing account is found, a new one is created.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ ConvertFrom-StringData @'
DomainNameAndWorkgroupNameError = Only DomainName or WorkGroupName can be specified at once.
ComputerNotInDomainMessage = This machine is not a domain member.
DeletedExistingComputerObject = Deleted existing computer object with name '{0}' at path '{1}'.
ReusingExistingComputerAccount = Reusing existing computer account for '{0}' at path '{1}'.
NoExistingComputerAccountFound = No existing computer account found for '{0}'. A new account will be created during join.
InvalidOptionPasswordPassUnsecuredJoin = Domain Join option 'PasswordPass' may not be specified if 'UnsecuredJoin' is specified.
InvalidOptionCredentialUnsecuredJoinNullUsername = 'Credential' username must be null if 'UnsecuredJoin' is specified.
'@
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<#PSScriptInfo
.VERSION 1.0.0
.GUID 3b2e8a4c-7f1d-4e2a-9c6b-8d5f3a1e7b9d
.AUTHOR DSC Community
.COMPANYNAME DSC Community
.COPYRIGHT Copyright the DSC Community contributors. All rights reserved.
.TAGS DSCConfiguration
.LICENSEURI https://github.com/dsccommunity/ComputerManagementDsc/blob/main/LICENSE
.PROJECTURI https://github.com/dsccommunity/ComputerManagementDsc
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES First version.
.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core
#>

#Requires -module ComputerManagementDsc

<#
.DESCRIPTION
This configuration sets the machine name to 'Server01' and
joins the 'Contoso' domain while reusing any existing computer
account in Active Directory. This preserves the machine SID,
group memberships, and GPO links.
Note: this requires an AD credential to join the domain.
#>
Configuration Computer_JoinDomainKeepExistingAccount_Config
{
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullorEmpty()]
[System.Management.Automation.PSCredential]
$Credential
)

Import-DscResource -Module ComputerManagementDsc

Node localhost
{
Computer JoinDomain
{
Name = 'Server01'
DomainName = 'Contoso'
Credential = $Credential # Credential to join to domain
ReuseExistingComputerAccount = $true # Reuse existing AD computer account
}
}
}
Loading