Skip to content

Commit

Permalink
Computer: Delete existing AD Computer object when joining Computer to…
Browse files Browse the repository at this point in the history
… Domain (#386)
  • Loading branch information
nickgw authored Jun 2, 2022
1 parent 49b3657 commit 438d2c2
Show file tree
Hide file tree
Showing 4 changed files with 326 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added

- Computer
- Support Options Parameter for domain join - Fixes [Issue #234](https://github.com/dsccommunity/ComputerManagementDsc/issues/234).
- When joining a computer to a domain, existing AD computer objects will be deleted - Fixes [Issue #55](https://github.com/dsccommunity/ComputerManagementDsc/issues/55), [Issue #58](https://github.com/dsccommunity/ComputerManagementDsc/issues/58).

## [8.5.0] - 2021-09-13

Expand Down
107 changes: 105 additions & 2 deletions source/DSCResources/DSC_Computer/DSC_Computer.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,15 @@ function Set-TargetResource
$addComputerParameters.Add("Server", $Server)
}

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

if ($computerObject)
{
Delete-ADSIObject -Path $computerObject.Path -Credential $Credential
Write-Verbose -Message ($script:localizedData.DeletedExistingComputerObject -f $Name, $computerObject.Path)
}

if (-not [System.String]::IsNullOrEmpty($Options))
{
<#
Expand Down Expand Up @@ -680,7 +689,100 @@ function Get-LogonServer
return $logonserver
}

Export-ModuleMember -Function *-TargetResource
<#
.SYNOPSIS
Returns an ADSI Computer Object.
.PARAMETER Name
Name of the computer to search for in the given domain.
.PARAMETER Domain
Domain to search.
.PARAMETER Credential
Credential to search domain with.
#>
function Get-ADSIComputer
{
[CmdletBinding()]
[OutputType([System.DirectoryServices.SearchResult])]
param
(
[Parameter(Mandatory = $true)]
[ValidateLength(1, 15)]
[ValidateScript( { $_ -inotmatch '[\/\\:*?"<>|]' })]
[System.String]
$Name,

[Parameter(Mandatory = $true)]
[System.String]
$DomainName,

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

$searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$searcher.Filter = "(&(objectCategory=computer)(objectClass=computer)(cn=$Name))"
if ($DomainName -notlike "LDAP://*")
{
$DomainName = "LDAP://$DomainName"
}

$params = @{
TypeName = 'System.DirectoryServices.DirectoryEntry'
ArgumentList = @(
$DomainName,
$Credential.UserName,
$Credential.GetNetworkCredential().password
)
ErrorAction = 'Stop'
}
$searchRoot = New-Object @params
$searcher.SearchRoot = $searchRoot

return $searcher.FindOne()
}

<#
.SYNOPSIS
Deletes an ADSI DirectoryEntry Object.
.PARAMETER Path
Path to Object to delete.
.PARAMETER Credential
Credential to authenticate to the domain.
#>
function Delete-ADSIObject
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateScript( { $_ -imatch "LDAP://*" })]
[System.String]
$Path,

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

$params = @{
TypeName = 'System.DirectoryServices.DirectoryEntry'
ArgumentList = @(
$DomainName,
$Credential.UserName
$Credential.GetNetworkCredential().password
)
ErrorAction = 'Stop'
}
$adsiObj = New-Object @params

$adsiObj.DeleteTree()
}

<#
.SYNOPSIS
Expand Down Expand Up @@ -774,5 +876,6 @@ function Assert-ResourceProperty
-Message $script:localizedData.InvalidOptionCredentialUnsecuredJoinNullUsername `
-ArgumentName 'Credential'
}

}

Export-ModuleMember -Function *-TargetResource
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ConvertFrom-StringData @'
CheckingWorkgroupMemberMessage = Checking if the machine is a member of workgroup '{0}'.
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}'.
InvalidOptionPasswordPassUnsecuredJoin = Domain Join option 'PasswordPass' may not be specified if 'UnsecuredJoin' is specified.
InvalidOptionCredentialUnsecuredJoinNullUsername = 'Credential' username must be null if 'UnsecuredJoin' is specified.
'@
Loading

0 comments on commit 438d2c2

Please sign in to comment.