Public/Computer/Set-AdAclCreateDeleteComputer.ps1
function Set-AdAclCreateDeleteComputer { <# .SYNOPSIS Delegates permission for a group to create/delete Computer objects in an OU. .DESCRIPTION Configures the container (OU) to delegate the permissions to a group so it can create/delete computer objects. This function assigns the necessary permissions for computer account creation and management. .PARAMETER Group Identity of the group getting the delegation, usually a DomainLocal group. .PARAMETER LDAPpath Distinguished Name of the OU where the permissions will be set. .PARAMETER RemoveRule If present, the access rules will be removed instead of added. .EXAMPLE Set-AdAclCreateDeleteComputer -Group "SG_SiteAdmins_XXXX" -LDAPPath "OU=Computers,OU=XXXX,OU=Sites,DC=EguibarIT,DC=local" Delegates Create/Delete computer permissions to the group "SG_SiteAdmins_XXXX" on the specified OU. .EXAMPLE Set-AdAclCreateDeleteComputer -Group "SG_SiteAdmins_XXXX" -LDAPPath "OU=Computers,OU=XXXX,OU=Sites,DC=EguibarIT,DC=local" -RemoveRule Removes the Create/Delete computer permissions from the group "SG_SiteAdmins_XXXX" on the specified OU. .INPUTS [String] Group [String] LDAPpath [Switch] RemoveRule .OUTPUTS None. This function does not generate any output. .NOTES Used Functions: Name ║ Module/Namespace ═══════════════════════════════════════════╬══════════════════════════════ Set-AclConstructor5 ║ EguibarIT.DelegationPS Get-AttributeSchemaHashTable ║ EguibarIT.DelegationPS Get-AdObjectType ║ EguibarIT.DelegationPS Test-IsValidDN ║ EguibarIT.DelegationPS Get-FunctionDisplay ║ EguibarIT.DelegationPS .NOTES Version: 1.3 DateModified: 11/May/2023 LastModifiedBy: Vicente Rodriguez Eguibar vicente@eguibar.com Eguibar Information Technology S.L. http://www.eguibarit.com .LINK https://github.com/vreguibar/EguibarIT.DelegationPS .COMPONENT Active Directory .ROLE Security, ActiveDirectory, Delegation .FUNCTIONALITY Delegation, Computer Management #> [CmdletBinding( SupportsShouldProcess = $true, ConfirmImpact = 'Medium' )] [OutputType([void])] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ValueFromRemainingArguments = $false, HelpMessage = 'Identity of the group getting the delegation, usually a DomainLocal group.', Position = 0)] [ValidateNotNullOrEmpty()] [Alias('IdentityReference', 'Identity', 'Trustee', 'GroupID')] $Group, [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ValueFromRemainingArguments = $false, HelpMessage = 'Distinguished Name of the OU where the permissions will be set.', Position = 1)] [ValidateNotNullOrEmpty()] [ValidateScript( { Test-IsValidDN -ObjectDN $_ }, ErrorMessage = 'Distinguished Name provided is not valid! Please check the format.' )] [Alias('DN', 'DistinguishedName')] [String] $LDAPpath, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ValueFromRemainingArguments = $false, HelpMessage = 'If present, the access rule will be removed.', Position = 2)] [ValidateNotNullOrEmpty()] [Switch] $RemoveRule ) Begin { Set-StrictMode -Version Latest # Display function header if variables exist if ($null -ne $Variables -and $null -ne $Variables.HeaderDelegation) { $txt = ($Variables.HeaderDelegation -f (Get-Date).ToString('dd/MMM/yyyy'), $MyInvocation.Mycommand, (Get-FunctionDisplay -HashTable $PsBoundParameters -Verbose:$False) ) Write-Verbose -Message $txt } #end if ############################## # Module imports ############################## # Variables Definition [Hashtable]$Splat = [hashtable]::New([StringComparer]::OrdinalIgnoreCase) try { Write-Verbose -Message 'Checking variable $Variables.GuidMap. In case it is empty, a function is called to fill it.' Get-AttributeSchemaHashTable # Verify Group exists and return it as Microsoft.ActiveDirectory.Management.AdGroup $CurrentGroup = Get-AdObjectType -Identity $PSBoundParameters['Group'] Write-Verbose -Message ('Group {0} found and ready for delegation' -f $PSBoundParameters['Group']) } catch { Write-Error -Message ('Error initializing variables or validating group: {0}' -f $_.Exception.Message) return } } #end Begin Process { <# ACE number: 1 -------------------------------------------------------- IdentityReference : XXX ActiveDirectoryRights : GenericAll AccessControlType : Allow ObjectType : computer [ClassSchema] InheritanceType : Descendents InheritedObjectType : GuidNULL IsInherited = False #> # Set the ACE for the group to have GenericAll permissions on descendant computer objects in the specified OU. $Splat = @{ Id = $CurrentGroup LDAPPath = $PSBoundParameters['LDAPpath'] AdRight = 'GenericAll' AccessControlType = 'Allow' ObjectType = $Variables.GuidMap['computer'] AdSecurityInheritance = 'Descendents' } # Check if RemoveRule switch is present If ($PSBoundParameters['RemoveRule']) { if ($PSCmdlet.ShouldProcess($PSBoundParameters['LDAPpath'], ('Remove GenericAll permissions for {0} on descendant computer objects' -f $PSBoundParameters['Group']))) { # Add the parameter to remove the rule $Splat.Add('RemoveRule', $true) Set-AclConstructor5 @Splat Write-Verbose -Message ( 'Removed GenericAll permission for {0} on descendant computer objects in {1}' -f $PSBoundParameters['Group'], $PSBoundParameters['LDAPpath'] ) } #end If } else { if ($PSCmdlet.ShouldProcess($PSBoundParameters['LDAPpath'], ('Grant GenericAll permissions for {0} on descendant computer objects' -f $PSBoundParameters['Group']))) { Set-AclConstructor5 @Splat Write-Verbose -Message ( 'Granted GenericAll permission for {0} on descendant computer objects in {1}' -f $PSBoundParameters['Group'], $PSBoundParameters['LDAPpath'] ) } #end If } #end If-Else <# ACE number: 2 -------------------------------------------------------- IdentityReference : XXX ActiveDirectoryRights : CreateChild, DeleteChild AccessControlType : Allow ObjectType : computer [ClassSchema] InheritanceType : All InheritedObjectType : GuidNULL IsInherited = False #> $Splat = @{ Id = $CurrentGroup LDAPPath = $PSBoundParameters['LDAPpath'] AdRight = 'CreateChild', 'DeleteChild' AccessControlType = 'Allow' ObjectType = $Variables.GuidMap['computer'] AdSecurityInheritance = 'All' } # Check if RemoveRule switch is present If ($PSBoundParameters['RemoveRule']) { if ($PSCmdlet.ShouldProcess($PSBoundParameters['LDAPpath'], ('Remove CreateChild/DeleteChild permissions for {0} on computer objects' -f $PSBoundParameters['Group']))) { # Add the parameter to remove the rule $Splat.Add('RemoveRule', $true) Set-AclConstructor5 @Splat Write-Verbose -Message ( 'Removed CreateChild/DeleteChild permissions for {0} in {1}' -f $PSBoundParameters['Group'], $PSBoundParameters['LDAPpath'] ) } #end If } else { if ($PSCmdlet.ShouldProcess($PSBoundParameters['LDAPpath'], ('Grant CreateChild/DeleteChild permissions for {0} on computer objects' -f $PSBoundParameters['Group']))) { Set-AclConstructor5 @Splat Write-Verbose -Message ('Granted CreateChild/DeleteChild permissions for {0} in {1}' -f $PSBoundParameters['Group'], $PSBoundParameters['LDAPpath']) } #end If } #end If-Else } #end Process End { # Display function footer if variables exist if ($null -ne $Variables -and $null -ne $Variables.FooterDelegation) { $ActionMessage = $(if ($PSBoundParameters['RemoveRule']) { 'removing' } else { 'delegating' }) $txt = ($Variables.FooterDelegation -f $MyInvocation.InvocationName, ('{0} Create/Delete computer permissions.' -f $ActionMessage) ) Write-Verbose -Message $txt } #end if } #end End } #end function Set-AdAclCreateDeleteComputer |