win_domain_user: added ability to explicitly set credentials and user when interacting with AD (#34562)

This commit is contained in:
Jordan Borean 2018-01-08 09:38:13 +10:00 committed by GitHub
parent e545127c2e
commit 71ff77e51f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 83 deletions

View file

@ -25,7 +25,7 @@ $organizational_unit = Get-AnsibleParam -obj $params -name "organizational_unit"
$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent"
$protect = Get-AnsibleParam -obj $params -name "protect" -type "bool"
$ignore_protection = Get-AnsibleParam -obj $params -name "ignore_protection" -type "bool" -default $false
$server = Get-AnsibleParam -obj $params -name "server" -type "str"
$domain_server = Get-AnsibleParam -obj $params -name "domain_server" -type "str"
$result = @{
changed = $false
@ -46,8 +46,8 @@ if ($domain_username -ne $null) {
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $domain_username, $domain_password
$extra_args.Credential = $credential
}
if ($server -ne $null) {
$extra_args.Server = $server
if ($domain_server -ne $null) {
$extra_args.Server = $domain_server
}
try {

View file

@ -45,6 +45,13 @@ options:
domain_password:
description:
- The password for C(username).
domain_server:
description:
- Specifies the Active Directory Domain Services instance to connect to.
- Can be in the form of an FQDN or NetBIOS name.
- If not specified then the value is based on the domain of the computer
running PowerShell.
version_added: '2.5'
ignore_protection:
description:
- Will ignore the C(ProtectedFromAccidentalDeletion) flag when deleting or
@ -89,13 +96,6 @@ options:
- If C(state=absent) this module will delete the group if it exists
default: present
choices: [ absent, present ]
server:
description:
- Specifies the Active Directory Domain Services instance to connect to.
- Can be in the form of an FQDN or NetBIOS name.
- If not specified then the value is based on the domain of the computer
running PowerShell.
version_added: '2.5'
notes:
- This must be run on a host that has the ActiveDirectory powershell module
installed.
@ -146,10 +146,10 @@ EXAMPLES = r'''
- name: add group and specify the AD domain services to use for the create
win_domain_group:
name: Test Group
domain_admin_user: user@CORP.ANSIBLE.COM
domain_admin_password: Password01!
domain_username: user@CORP.ANSIBLE.COM
domain_password: Password01!
domain_server: corp-DC12.corp.ansible.com
scope: domainlocal
server: corp-DC12.corp.ansible.com
'''
RETURN = r'''

View file

@ -1,23 +1,10 @@
#!powershell
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# WANT_JSON
# POWERSHELL_COMMON
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#Requires -Module Ansible.ModuleUtils.Legacy
########
try {
Import-Module ActiveDirectory
}
@ -30,6 +17,8 @@ $result = @{
password_updated = $false
}
$ErrorActionPreference = "Stop"
$params = Parse-Args $args -supports_check_mode $true
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false
@ -37,6 +26,9 @@ $check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default
$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent","query"
$update_password = Get-AnsibleParam -obj $params -name "update_password" -type "str" -default "always" -validateset "always","on_create"
$groups_action = Get-AnsibleParam -obj $params -name "groups_action" -type "str" -default "replace" -validateset "add","remove","replace"
$domain_username = Get-AnsibleParam -obj $params -name "domain_username" -type "str"
$domain_password = Get-AnsibleParam -obj $params -name "domain_password" -type "str" -failifempty ($domain_username -ne $null)
$domain_server = Get-AnsibleParam -obj $params -name "domain_server" -type "str"
# User account parameters
$username = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true
@ -75,8 +67,18 @@ If (($password_expired -ne $null) -and ($password_never_expires -ne $null)) {
Fail-Json $result "password_expired and password_never_expires are mutually exclusive but have both been set"
}
$extra_args = @{}
if ($domain_username -ne $null) {
$domain_password = ConvertTo-SecureString $domain_password -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $domain_username, $domain_password
$extra_args.Credential = $credential
}
if ($domain_server -ne $null) {
$extra_args.Server = $domain_server
}
try {
$user_obj = Get-ADUser -Identity $username -Properties *
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
}
catch {
$user_obj = $null
@ -90,64 +92,64 @@ If ($state -eq 'present') {
# If the account does not exist, create it
If (-not $user_obj) {
If ($path -ne $null){
New-ADUser -Name $username -Path $path -WhatIf:$check_mode
New-ADUser -Name $username -Path $path -WhatIf:$check_mode @extra_args
}
Else {
New-ADUser -Name $username -WhatIf:$check_mode
New-ADUser -Name $username -WhatIf:$check_mode @extra_args
}
$new_user = $true
$result.changed = $true
If ($check_mode) {
Exit-Json $result
}
$user_obj = Get-ADUser -Identity $username -Properties *
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
}
# Set the password if required
If ($password -and (($new_user -and $update_password -eq "on_create") -or $update_password -eq "always")) {
$secure_password = ConvertTo-SecureString $password -AsPlainText -Force
Set-ADAccountPassword -Identity $username -Reset:$true -Confirm:$false -NewPassword $secure_password -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Set-ADAccountPassword -Identity $username -Reset:$true -Confirm:$false -NewPassword $secure_password -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.password_updated = $true
$result.changed = $true
}
# Configure password policies
If (($password_never_expires -ne $null) -and ($password_never_expires -ne $user_obj.PasswordNeverExpires)) {
Set-ADUser -Identity $username -PasswordNeverExpires $password_never_expires -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Set-ADUser -Identity $username -PasswordNeverExpires $password_never_expires -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
If (($password_expired -ne $null) -and ($password_expired -ne $user_obj.PasswordExpired)) {
Set-ADUser -Identity $username -ChangePasswordAtLogon $password_expired -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Set-ADUser -Identity $username -ChangePasswordAtLogon $password_expired -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
If (($user_cannot_change_password -ne $null) -and ($user_cannot_change_password -ne $user_obj.CannotChangePassword)) {
Set-ADUser -Identity $username -CannotChangePassword $user_cannot_change_password -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Set-ADUser -Identity $username -CannotChangePassword $user_cannot_change_password -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
# Assign other account settings
If (($upn -ne $null) -and ($upn -ne $user_obj.UserPrincipalName)) {
Set-ADUser -Identity $username -UserPrincipalName $upn -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Set-ADUser -Identity $username -UserPrincipalName $upn -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
If (($description -ne $null) -and ($description -ne $user_obj.Description)) {
Set-ADUser -Identity $username -description $description -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Set-ADUser -Identity $username -description $description -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
If ($enabled -ne $user_obj.Enabled) {
Set-ADUser -Identity $username -Enabled $enabled -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Set-ADUser -Identity $username -Enabled $enabled -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
If ((-not $account_locked) -and ($user_obj.LockedOut -eq $true)) {
Unlock-ADAccount -Identity $username -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Unlock-ADAccount -Identity $username -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
@ -158,17 +160,16 @@ If ($state -eq 'present') {
}
$value = $user_info[$key]
If ($value -ne $user_obj.$key) {
$expression = "Set-ADUser -Identity $username -$key '$value'"
If (-not $check_mode) {
Invoke-Expression $expression
}
$set_args = $extra_args.Clone()
$set_args.$key = $value
Set-ADUser -Identity $username -WhatIf:$check_mode @set_args
$result.changed = $true
$user_obj = Get-ADUser -Identity $username -Properties *
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
}
}
# Set additional attributes
$set_args = @{}
$set_args = $extra_args.Clone()
$run_change = $false
if ($attributes -ne $null) {
$add_attributes = @{}
@ -213,11 +214,11 @@ If ($state -eq 'present') {
$groups = @()
Foreach ($group in $group_list) {
$groups += (Get-ADGroup -Identity $group).DistinguishedName
$groups += (Get-ADGroup -Identity $group @extra_args).DistinguishedName
}
$assigned_groups = @()
Foreach ($group in (Get-ADPrincipalGroupMembership -Identity $username)) {
Foreach ($group in (Get-ADPrincipalGroupMembership -Identity $username @extra_args)) {
$assigned_groups += $group.DistinguishedName
}
@ -225,8 +226,8 @@ If ($state -eq 'present') {
"add" {
Foreach ($group in $groups) {
If (-not ($assigned_groups -Contains $group)) {
Add-ADGroupMember -Identity $group -Members $username -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Add-ADGroupMember -Identity $group -Members $username -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
}
@ -234,8 +235,8 @@ If ($state -eq 'present') {
"remove" {
Foreach ($group in $groups) {
If ($assigned_groups -Contains $group) {
Remove-ADGroupMember -Identity $group -Members $username -Confirm:$false -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Remove-ADGroupMember -Identity $group -Members $username -Confirm:$false -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
}
@ -243,15 +244,15 @@ If ($state -eq 'present') {
"replace" {
Foreach ($group in $assigned_groups) {
If (($group -ne $user_obj.PrimaryGroup) -and -not ($groups -Contains $group)) {
Remove-ADGroupMember -Identity $group -Members $username -Confirm:$false -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Remove-ADGroupMember -Identity $group -Members $username -Confirm:$false -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
}
Foreach ($group in $groups) {
If (-not ($assigned_groups -Contains $group)) {
Add-ADGroupMember -Identity $group -Members $username -WhatIf:$check_mode
$user_obj = Get-ADUser -Identity $username -Properties *
Add-ADGroupMember -Identity $group -Members $username -WhatIf:$check_mode @extra_args
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.changed = $true
}
}
@ -267,7 +268,7 @@ If ($state -eq 'present') {
# Ensure user does not exist
try {
If ($user_obj) {
Remove-ADUser $user_obj -Confirm:$false -WhatIf:$check_mode
Remove-ADUser $user_obj -Confirm:$false -WhatIf:$check_mode @extra_args
$result.changed = $true
If ($check_mode) {
Exit-Json $result
@ -282,7 +283,7 @@ If ($state -eq 'present') {
try {
If ($user_obj) {
$user_obj = Get-ADUser -Identity $username -Properties *
$user_obj = Get-ADUser -Identity $username -Properties * @extra_args
$result.name = $user_obj.Name
$result.firstname = $user_obj.GivenName
$result.surname = $user_obj.Surname
@ -303,7 +304,7 @@ try {
$result.sid = [string]$user_obj.SID
$result.upn = $user_obj.UserPrincipalName
$user_groups = @()
Foreach ($group in (Get-ADPrincipalGroupMembership $username)) {
Foreach ($group in (Get-ADPrincipalGroupMembership $username @extra_args)) {
$user_groups += $group.name
}
$result.groups = $user_groups

View file

@ -1,20 +1,9 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# this is a windows documentation stub. actual code lives in the .ps1
# file of the same name
@ -155,10 +144,28 @@ options:
parameters, e.g. C(telephoneNumber).
- See the examples on how to format this parameter.
version_added: "2.5"
domain_username:
description:
- The username to use when interacting with AD.
- If this is not set then the user Ansible used to log in with will be
used instead when using CredSSP or Kerberos with credential delegation.
version_added: '2.5'
domain_password:
description:
- The password for C(username).
version_added: '2.5'
domain_server:
description:
- Specifies the Active Directory Domain Services instance to connect to.
- Can be in the form of an FQDN or NetBIOS name.
- If not specified then the value is based on the domain of the computer
running PowerShell.
version_added: '2.5'
notes:
- Works with Windows 2012R2 and newer.
- If running on a server that is not a Domain Controller, credential
delegation through CredSSP or Kerberos with delegation must be used.
delegation through CredSSP or Kerberos with delegation must be used or the
I(domain_username), I(domain_password) must be set.
- Note that some individuals have confirmed successful operation on Windows
2008R2 servers with AD and AD Web Services enabled, but this has not
received the same degree of testing as Windows 2012R2.
@ -185,6 +192,17 @@ EXAMPLES = r'''
attributes:
telephoneNumber: 555-123456
- name: Ensure user bob is created and use custom credentials to create the user
win_domain_user:
name: bob
firstname: Bob
surname: Smith
password: B0bP4ssw0rd
state: present
domain_username: DOMAIN\admin-account
domain_password: SomePas2w0rd
domain_server: domain@DOMAIN.COM
- name: Ensure user bob is present in OU ou=test,dc=domain,dc=local
win_domain_user:
name: bob