diff --git a/plugins/modules/win_domain_user.ps1 b/plugins/modules/win_domain_user.ps1 index a3df9b13..294085a1 100644 --- a/plugins/modules/win_domain_user.ps1 +++ b/plugins/modules/win_domain_user.ps1 @@ -36,7 +36,8 @@ Function Test-Credential { $failed_codes = @( 0x0000052E, # ERROR_LOGON_FAILURE 0x00000532, # ERROR_PASSWORD_EXPIRED - 0x00000773 # ERROR_PASSWORD_MUST_CHANGE + 0x00000773, # ERROR_PASSWORD_MUST_CHANGE + 0x00000533 # ERROR_ACCOUNT_DISABLED ) if ($_.Exception.NativeErrorCode -in $failed_codes) { @@ -199,7 +200,11 @@ If ($state -eq 'present') { } If ($set_new_credentials) { $secure_password = ConvertTo-SecureString $password -AsPlainText -Force - Set-ADAccountPassword -Identity $user_guid -Reset:$true -Confirm:$false -NewPassword $secure_password -WhatIf:$check_mode @extra_args + try { + Set-ADAccountPassword -Identity $user_guid -Reset:$true -Confirm:$false -NewPassword $secure_password -WhatIf:$check_mode @extra_args + }catch{ + Fail-Json $result "Failed to set password on account" + } $user_obj = Get-ADUser -Identity $user_guid -Properties * @extra_args $result.password_updated = $true $result.changed = $true diff --git a/tests/integration/targets/win_domain_user/.DS_Store b/tests/integration/targets/win_domain_user/.DS_Store new file mode 100644 index 00000000..f112d67c Binary files /dev/null and b/tests/integration/targets/win_domain_user/.DS_Store differ diff --git a/tests/integration/targets/win_domain_user/aliases b/tests/integration/targets/win_domain_user/aliases new file mode 100644 index 00000000..22f581bf --- /dev/null +++ b/tests/integration/targets/win_domain_user/aliases @@ -0,0 +1,2 @@ +shippable/windows/group2 +skip/windows/2012 diff --git a/tests/integration/targets/win_domain_user/meta/main.yml b/tests/integration/targets/win_domain_user/meta/main.yml new file mode 100644 index 00000000..da6e52e2 --- /dev/null +++ b/tests/integration/targets/win_domain_user/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - setup_domain_tests diff --git a/tests/integration/targets/win_domain_user/tasks/check_mode_test.yml b/tests/integration/targets/win_domain_user/tasks/check_mode_test.yml new file mode 100644 index 00000000..e7f1faa7 --- /dev/null +++ b/tests/integration/targets/win_domain_user/tasks/check_mode_test.yml @@ -0,0 +1,23 @@ +--- + +- name: Create Jane(check_mode) + community.windows.win_domain_user: + name: Jane + password: J@n3P4ssw0rd# + state: present + update_password: on_create + account_locked: false + password_never_expires: false + enabled: true + register: new_user_check_mode + failed_when: + - not new_user_check_mode.changed + - not new_user_check_mode.created + check_mode: true + +- name: Sanity check on Check Mode + win_shell: | + Get-AdUser -Identity Jane + register: sanity_check + failed_when: "'NotFound' not in sanity_check.stderr" + changed_when: false diff --git a/tests/integration/targets/win_domain_user/tasks/main.yml b/tests/integration/targets/win_domain_user/tasks/main.yml new file mode 100644 index 00000000..1ea02d5e --- /dev/null +++ b/tests/integration/targets/win_domain_user/tasks/main.yml @@ -0,0 +1,6 @@ +--- +- name: Run Tests + import_tasks: tests.yml + +- name: Run Check Mode Tests + import_tasks: check_mode_test.yml \ No newline at end of file diff --git a/tests/integration/targets/win_domain_user/tasks/tests.yml b/tests/integration/targets/win_domain_user/tasks/tests.yml new file mode 100644 index 00000000..b90ccfca --- /dev/null +++ b/tests/integration/targets/win_domain_user/tasks/tests.yml @@ -0,0 +1,121 @@ +--- +- name: Create Jane + community.windows.win_domain_user: + name: Jane + password: J@n3P4ssw0rd# + state: present + update_password: on_create + account_locked: false + password_never_expires: false + enabled: true + register: new_user_test + failed_when: new_user_test is not success + +- name: Create Jane (idempotence check) + community.windows.win_domain_user: + name: Jane + password: J@n3P4ssw0rd# + state: present + update_password: on_create + account_locked: false + password_never_expires: false + enabled: true + register: new_user_test_idempotent + failed_when: new_user_test_idempotent is changed + +- name: Create Jane update password + community.windows.win_domain_user: + name: Jane + password: J@n3P4ssw0rd# + state: present + update_password: always + account_locked: false + password_never_expires: false + enabled: true + register: password_changed + failed_when: not password_changed.changed + +- name: Create user with invalid password + community.windows.win_domain_user: + name: bob + upn: Bob@ansible.test + firstname: Bob + surname: Smith + company: BobCo + password: 123 + state: present + groups: + - Domain Admins + street: 123 4th St. + city: Sometown + state_province: IN + postal_code: 12345 + country: US + attributes: + telephoneNumber: 555-123456 + update_password: when_changed + password_never_expires: true + register: bad_password_test + failed_when: bad_password_test is success + +- name: Create user again with valid password + community.windows.win_domain_user: + name: bob + upn: Bob@ansible.test + firstname: Bob + surname: Smith + company: BobCo + password: B0bP4ssw0rd + state: present + groups: + - Domain Admins + street: 123 4th St. + city: Sometown + state_province: IN + postal_code: 12345 + country: US + attributes: + telephoneNumber: 555-123456 + update_password: when_changed + password_never_expires: true + register: good_password_test + failed_when: good_password_test is not success + +- name: Remove bob + community.windows.win_domain_user: + name: bob + state: absent + register: user_removed + failed_when: not user_removed.changed + +- name: Remove bob (idempotence check) + community.windows.win_domain_user: + name: bob + state: absent + register: user_removed_idempotent + failed_when: user_removed_idempotent.changed + +- name: Remove Jane + community.windows.win_domain_user: + name: Jane + state: absent + +- name: Assertions + assert: + that: + - new_user_test.changed + - new_user_test.created + - not new_user_test.password_never_expires + - not new_user_test_idempotent.changed + - new_user_test_idempotent.distinguished_name == "CN=Jane,CN=Users,DC=ansible,DC=test" + - password_changed.changed + - password_changed.password_updated + - bad_password_test.changed + - bad_password_test.created + - good_password_test.changed + - good_password_test.upn == "Bob@ansible.test" + - good_password_test.password_never_expires + - good_password_test.company == "BobCo" + - not good_password_test.created + - good_password_test.password_updated + - user_removed.state == "absent"