diff options
Diffstat (limited to 'ansible_collections/microsoft/ad/plugins/modules/group.ps1')
-rw-r--r-- | ansible_collections/microsoft/ad/plugins/modules/group.ps1 | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/ansible_collections/microsoft/ad/plugins/modules/group.ps1 b/ansible_collections/microsoft/ad/plugins/modules/group.ps1 new file mode 100644 index 000000000..bbb3aa8d7 --- /dev/null +++ b/ansible_collections/microsoft/ad/plugins/modules/group.ps1 @@ -0,0 +1,211 @@ +#!powershell + +# Copyright: (c) 2023, Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +#AnsibleRequires -CSharpUtil Ansible.Basic +#AnsibleRequires -PowerShell ..module_utils._ADObject + +$setParams = @{ + PropertyInfo = @( + [PSCustomObject]@{ + Name = 'category' + Option = @{ + choices = 'distribution', 'security' + type = 'str' + } + Attribute = 'GroupCategory' + CaseInsensitive = $true + } + [PSCustomObject]@{ + Name = 'homepage' + Option = @{ type = 'str' } + Attribute = 'Homepage' + } + [PSCustomObject]@{ + Name = 'managed_by' + Option = @{ type = 'str' } + Attribute = 'ManagedBy' + } + [PSCustomObject]@{ + Name = 'members' + Option = @{ + type = 'dict' + options = @{ + add = @{ + type = 'list' + elements = 'str' + } + remove = @{ + type = 'list' + elements = 'str' + } + set = @{ + type = 'list' + elements = 'str' + } + } + } + Attribute = 'member' + New = { + param($Module, $ADParams, $NewParams) + + $newMembers = @( + foreach ($actionKvp in $Module.Params.members.GetEnumerator()) { + if ($null -eq $actionKvp.Value -or $actionKvp.Key -eq 'remove') { continue } + + $invalidMembers = [System.Collections.Generic.List[string]]@() + + foreach ($m in $actionKvp.Value) { + $obj = Get-AnsibleADObject -Identity $m @ADParams | + Select-Object -ExpandProperty DistinguishedName + if ($obj) { + $obj + } + else { + $invalidMembers.Add($m) + } + } + + if ($invalidMembers) { + $module.FailJson("Failed to find the following ad objects for group members: '$($invalidMembers -join "', '")'") + } + } + ) + + if ($newMembers) { + if (-not $NewParams.ContainsKey('OtherAttributes')) { + $NewParams.OtherAttributes = @{} + } + # The AD cmdlets don't like explicitly casted arrays, use + # ForEach-Object to get back a vanilla object[] to set. + $NewParams.OtherAttributes.member = $newMembers | ForEach-Object { "$_" } + } + $Module.Diff.after.members = @($newMembers | Sort-Object) + } + Set = { + param($Module, $ADParams, $SetParams, $ADObject) + + [string[]]$existingMembers = $ADObject.member + + $desiredState = @{} + foreach ($actionKvp in $Module.Params.members.GetEnumerator()) { + if ($null -eq $actionKvp.Value) { continue } + + $invalidMembers = [System.Collections.Generic.List[string]]@() + + $dns = foreach ($m in $actionKvp.Value) { + $obj = Get-AnsibleADObject -Identity $m @ADParams | + Select-Object -ExpandProperty DistinguishedName + if ($obj) { + $obj + } + else { + $invalidMembers.Add($m) + } + } + + if ($invalidMembers) { + $module.FailJson("Failed to find the following ad objects for group members: '$($invalidMembers -join "', '")'") + } + + $desiredState[$actionKvp.Key] = @($dns) + } + + $ignoreCase = [System.StringComparer]::OrdinalIgnoreCase + [string[]]$diffAfter = @() + if ($desiredState.ContainsKey('set')) { + [string[]]$desiredMembers = $desiredState.set + $diffAfter = $desiredMembers + + $toAdd = [string[]][System.Linq.Enumerable]::Except($desiredMembers, $existingMembers, $ignoreCase) + $toRemove = [string[]][System.Linq.Enumerable]::Except($existingMembers, $desiredMembers, $ignoreCase) + + if ($toAdd -or $toRemove) { + if (-not $SetParams.ContainsKey('Replace')) { + $SetParams.Replace = @{} + } + $SetParams.Replace.member = $desiredMembers + } + } + else { + [string[]]$toAdd = @() + [string[]]$toRemove = @() + $diffAfter = $existingMembers + + if ($desiredState.ContainsKey('add') -and $desiredState.add) { + [string[]]$desiredMembers = $desiredState.add + $toAdd = [string[]][System.Linq.Enumerable]::Except($desiredMembers, $existingMembers, $ignoreCase) + $diffAfter = [System.Linq.Enumerable]::Union($desiredMembers, $diffAfter, $ignoreCase) + } + if ($desiredState.ContainsKey('remove') -and $desiredState.remove) { + + [string[]]$desiredMembers = $desiredState.remove + $toRemove = [string[]][System.Linq.Enumerable]::Intersect($desiredMembers, $existingMembers, $ignoreCase) + $diffAfter = [System.Linq.Enumerable]::Except($diffAfter, $desiredMembers, $ignoreCase) + } + + if ($toAdd) { + if (-not $SetParams.ContainsKey('Add')) { + $SetParams.Add = @{} + } + $SetParams.Add.member = $toAdd + } + if ($toRemove) { + if (-not $SetParams.ContainsKey('Remove')) { + $SetParams.Remove = @{} + } + $SetParams.Remove.member = $toRemove + } + } + + $Module.Diff.after.members = ($diffAfter | Sort-Object) + } + } + [PSCustomObject]@{ + Name = 'sam_account_name' + Option = @{ type = 'str' } + Attribute = 'sAMAccountName' + } + [PSCustomObject]@{ + Name = 'scope' + Option = @{ + choices = 'domainlocal', 'global', 'universal' + type = 'str' + } + Attribute = 'GroupScope' + CaseInsensitive = $true + } + ) + ModuleNoun = 'ADGroup' + DefaultPath = { + param($Module, $ADParams) + + $GUID_USERS_CONTAINER_W = 'A9D1CA15768811D1ADED00C04FD8D5CD' + $defaultNamingContext = (Get-ADRootDSE @ADParams -Properties defaultNamingContext).defaultNamingContext + + Get-ADObject @ADParams -Identity $defaultNamingContext -Properties wellKnownObjects | + Select-Object -ExpandProperty wellKnownObjects | + Where-Object { $_.StartsWith("B:32:$($GUID_USERS_CONTAINER_W):") } | + ForEach-Object Substring 38 + } + PreAction = { + param ($Module, $ADParams, $ADObject) + + if ($Module.Params.state -eq 'present' -and (-not $Module.Params.scope) -and (-not $ADObject)) { + $Module.FailJson("scope must be set when state=present and the group does not exist") + } + } + PostAction = { + param($Module, $ADParams, $ADObject) + + if ($ADObject) { + $Module.Result.sid = $ADObject.SID.Value + } + elseif ($Module.Params.state -eq 'present') { + # Use dummy value for check mode when creating a new user + $Module.Result.sid = 'S-1-5-0000' + } + } +} +Invoke-AnsibleADObject @setParams |