summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSlava Maslennikov <smaslennikov@users.noreply.github.com>2019-03-28 05:36:26 +0100
committerJordan Borean <jborean93@gmail.com>2019-03-28 05:36:26 +0100
commit85d836171b6cd5a07ff49955335444680c110ea3 (patch)
tree0fb2d7e7078608a64e36a5a34f3c4e45264f775f
parentCatch all request timeouts for winrm connection (#54104) (diff)
downloadansible-85d836171b6cd5a07ff49955335444680c110ea3.tar.xz
ansible-85d836171b6cd5a07ff49955335444680c110ea3.zip
Add a force_replace_host flag to win_domain_membership (#53542)
* Add a force_replace_host flag to win_domain_membership Satisfies https://github.com/ansible/ansible/issues/53539 * Rework backticks * Bump version_added * Check for existence of current hostname as well; use LDAPFilter during search * Rename $force_replace_host to $allow_existing_computer_account * Added docs, porting guide and minor nit in code
-rw-r--r--changelogs/fragments/win_domain_membership-replace.yaml2
-rw-r--r--docs/docsite/rst/porting_guides/porting_guide_2.8.rst4
-rw-r--r--lib/ansible/modules/windows/win_domain_membership.ps122
-rw-r--r--lib/ansible/modules/windows/win_domain_membership.py7
-rw-r--r--test/sanity/pslint/ignore.txt1
5 files changed, 29 insertions, 7 deletions
diff --git a/changelogs/fragments/win_domain_membership-replace.yaml b/changelogs/fragments/win_domain_membership-replace.yaml
new file mode 100644
index 0000000000..73cadd249b
--- /dev/null
+++ b/changelogs/fragments/win_domain_membership-replace.yaml
@@ -0,0 +1,2 @@
+minor_changes:
+- win_domain_membership - will now fail if an existing AD object for the host exists and ``allow_existing_computer_account=no`` - https://github.com/ansible/ansible/pull/53542
diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.8.rst b/docs/docsite/rst/porting_guides/porting_guide_2.8.rst
index 969c5fad79..3512f19fa1 100644
--- a/docs/docsite/rst/porting_guides/porting_guide_2.8.rst
+++ b/docs/docsite/rst/porting_guides/porting_guide_2.8.rst
@@ -315,6 +315,10 @@ Noteworthy module changes
* The ``win_dsc`` module will now validate the input options for a DSC resource. In previous versions invalid options
would be ignored but are now not.
+* The ``win_domain_membership`` module will no longer automatically join a host in a domain that already has an account
+ with the same name. Set ``allow_existing_computer_account=yes`` to override this check and go back to the original
+ behaviour.
+
Plugins
=======
diff --git a/lib/ansible/modules/windows/win_domain_membership.ps1 b/lib/ansible/modules/windows/win_domain_membership.ps1
index e08e17c158..32b5f3eb0e 100644
--- a/lib/ansible/modules/windows/win_domain_membership.ps1
+++ b/lib/ansible/modules/windows/win_domain_membership.ps1
@@ -47,11 +47,11 @@ Function Get-DomainMembershipMatch {
}
catch [System.Security.Authentication.AuthenticationException] {
Write-DebugLog "Failed to get computer domain. Attempting a different method."
- Add-Type -AssemblyName System.DirectoryServices.AccountManagement
+ Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$user_principal = [System.DirectoryServices.AccountManagement.UserPrincipal]::Current
If ($user_principal.ContextType -eq "Machine") {
$current_dns_domain = (Get-CimInstance -ClassName Win32_ComputerSystem -Property Domain).Domain
-
+
$domain_match = $current_dns_domain -eq $dns_domain_name
Write-DebugLog ("current domain {0} matches {1}: {2}" -f $current_dns_domain, $dns_domain_name, $domain_match)
@@ -102,7 +102,8 @@ Function Join-Domain {
[string] $new_hostname,
[string] $domain_admin_user,
[string] $domain_admin_password,
- [string] $domain_ou_path
+ [string] $domain_ou_path,
+ [bool] $allow_existing_computer_account
)
Write-DebugLog ("Creating credential for user {0}" -f $domain_admin_user)
@@ -118,17 +119,24 @@ Function Join-Domain {
Write-DebugLog "adding hostname set arg to Add-Computer args"
If($new_hostname) {
$add_args["NewName"] = $new_hostname
+ $hostname_in_domain = Get-ADObject -LDAPFilter "(&(CN=$new_hostname)(ObjectClass=Computer))"
+ } else {
+ $hostname_in_domain = Get-ADObject -LDAPFilter "(&(CN=$env:COMPUTERNAME)(ObjectClass=Computer))"
}
-
if($domain_ou_path){
Write-DebugLog "adding OU destination arg to Add-Computer args"
$add_args["OUPath"] = $domain_ou_path
}
+
$argstr = $add_args | Out-String
Write-DebugLog "calling Add-Computer with args: $argstr"
try {
- $add_result = Add-Computer @add_args
+ if($null -eq $hostname_in_domain -or ($null -ne $hostname_in_domain -and $allow_existing_computer_account)) {
+ $add_result = Add-Computer @add_args
+ } else {
+ Fail-Json -obj $result -message "failed to join domain: hostname already exists in AD and allow_existing_computer_account=no"
+ }
} catch {
Fail-Json -obj $result -message "failed to join domain: $($_.Exception.Message)"
}
@@ -154,7 +162,7 @@ Function Set-Workgroup {
if ($swg_result.ReturnValue -ne 0) {
Fail-Json -obj $result -message "failed to set workgroup through WMI, return value: $($swg_result.ReturnValue)"
-
+
return $swg_result}
}
@@ -198,6 +206,7 @@ $workgroup_name = Get-AnsibleParam $params "workgroup_name"
$domain_admin_user = Get-AnsibleParam $params "domain_admin_user" -failifempty $result
$domain_admin_password = Get-AnsibleParam $params "domain_admin_password" -failifempty $result
$domain_ou_path = Get-AnsibleParam $params "domain_ou_path"
+$allow_existing_computer_account = Get-AnsibleParam $params "allow_existing_computer_account" -type "bool" -default $false
$log_path = Get-AnsibleParam $params "log_path"
$_ansible_check_mode = Get-AnsibleParam $params "_ansible_check_mode" -default $false
@@ -239,6 +248,7 @@ Try {
dns_domain_name = $dns_domain_name
domain_admin_user = $domain_admin_user
domain_admin_password = $domain_admin_password
+ allow_existing_computer_account = $allow_existing_computer_account
}
Write-DebugLog "not a domain member, joining..."
diff --git a/lib/ansible/modules/windows/win_domain_membership.py b/lib/ansible/modules/windows/win_domain_membership.py
index e74a0d8c01..7d40526751 100644
--- a/lib/ansible/modules/windows/win_domain_membership.py
+++ b/lib/ansible/modules/windows/win_domain_membership.py
@@ -48,6 +48,13 @@ options:
description:
- When C(state) is C(workgroup), the name of the workgroup that the Windows host should be in.
type: str
+ allow_existing_computer_account:
+ description:
+ - If a host with the same hostname is already in the AD, replace it.
+ type: bool
+ choices: [ true, false ]
+ default: false
+ version_added: "2.8"
seealso:
- module: win_domain
- module: win_domain_controller
diff --git a/test/sanity/pslint/ignore.txt b/test/sanity/pslint/ignore.txt
index 544a3cde1b..b68890576c 100644
--- a/test/sanity/pslint/ignore.txt
+++ b/test/sanity/pslint/ignore.txt
@@ -57,7 +57,6 @@ lib/ansible/modules/windows/win_domain_controller.ps1 PSUseApprovedVerbs
lib/ansible/modules/windows/win_domain_controller.ps1 PSUseDeclaredVarsMoreThanAssignments
lib/ansible/modules/windows/win_domain_group.ps1 PSAvoidTrailingWhitespace
lib/ansible/modules/windows/win_domain_membership.ps1 PSAvoidGlobalVars
-lib/ansible/modules/windows/win_domain_membership.ps1 PSAvoidTrailingWhitespace
lib/ansible/modules/windows/win_domain_membership.ps1 PSAvoidUsingWMICmdlet
lib/ansible/modules/windows/win_domain_membership.ps1 PSCustomUseLiteralPath
lib/ansible/modules/windows/win_domain_membership.ps1 PSUseApprovedVerbs