#!powershell # Copyright: (c) 2019, Marius Rieder # 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 } catch { Fail-Json -obj @{} -message "win_domain_group_membership requires the ActiveDirectory PS module to be installed" } $params = Parse-Args $args -supports_check_mode $true $check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false $diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false # Module control parameters $state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent","pure" $domain_username = Get-AnsibleParam -obj $params -name "domain_username" -type "str" $domain_password = Get-AnsibleParam -obj $params -name "domain_password" -type "str" -failifempty ($null -ne $domain_username) $domain_server = Get-AnsibleParam -obj $params -name "domain_server" -type "str" # Group Membership parameters $name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true $members = Get-AnsibleParam -obj $params -name "members" -type "list" -failifempty $true # Filter ADObjects by ObjectClass $ad_object_class_filter = "(ObjectClass -eq 'user' -or ObjectClass -eq 'group' -or ObjectClass -eq 'computer' -or ObjectClass -eq 'msDS-ManagedServiceAccount')" $extra_args = @{} if ($null -ne $domain_username) { $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 ($nul -ne $domain_server) { $extra_args.Server = $domain_server } $result = @{ changed = $false added = [System.Collections.Generic.List`1[String]]@() removed = [System.Collections.Generic.List`1[String]]@() } if ($diff_mode) { $result.diff = @{} } $members_before = Get-AdGroupMember -Identity $name @extra_args $pure_members = [System.Collections.Generic.List`1[String]]@() foreach ($member in $members) { $group_member = Get-ADObject -Filter "SamAccountName -eq '$member' -and $ad_object_class_filter" -Properties objectSid, sAMAccountName if (!$group_member) { Fail-Json -obj $result "Could not find domain user, group, service account or computer named $member" } if ($state -eq "pure") { $pure_members.Add($group_member.objectSid) } $user_in_group = $false foreach ($current_member in $members_before) { if ($current_member.sid -eq $group_member.objectSid) { $user_in_group = $true break } } if ($state -in @("present", "pure") -and !$user_in_group) { Add-ADGroupMember -Identity $name -Members $group_member -WhatIf:$check_mode @extra_args $result.added.Add($group_member.SamAccountName) $result.changed = $true } elseif ($state -eq "absent" -and $user_in_group) { Remove-ADGroupMember -Identity $name -Members $group_member -WhatIf:$check_mode @extra_args -Confirm:$False $result.removed.Add($group_member.SamAccountName) $result.changed = $true } } if ($state -eq "pure") { # Perform removals for existing group members not defined in $members $current_members = Get-AdGroupMember -Identity $name @extra_args foreach ($current_member in $current_members) { $user_to_remove = $true foreach ($pure_member in $pure_members) { if ($pure_member -eq $current_member.sid) { $user_to_remove = $false break } } if ($user_to_remove) { Remove-ADGroupMember -Identity $name -Members $current_member -WhatIf:$check_mode @extra_args -Confirm:$False $result.removed.Add($current_member.SamAccountName) $result.changed = $true } } } $final_members = Get-AdGroupMember -Identity $name @extra_args if ($final_members) { $result.members = [Array]$final_members.SamAccountName } else { $result.members = @() } if ($diff_mode -and $result.changed) { $result.diff.before = $members_before.SamAccountName | Out-String if (!$check_mode) { $result.diff.after = [Array]$final_members.SamAccountName | Out-String } else { $after = [System.Collections.Generic.List`1[String]]$result.members $result.removed | ForEach-Object { $after.Remove($_) > $null } $after.AddRange($result.added) $result.diff.after = $after | Out-String } } Exit-Json -obj $result