<# .SYNOPSIS Creates a Tier 0 admin group and delegates full control of the Tier 0 OU tree to it. .DESCRIPTION Builds the delegation piece of a tiered admin model: one security group whose members manage everything under the Tier 0 OU. The script creates the group (inside Tier 0, so only Tier 0 can change who's in it), adds any members you name, and adds an inheritable Full Control entry to the Tier 0 OU's ACL. It's safe to re-run: existing groups, members and permissions are left alone. Supports -WhatIf. .PARAMETER Tier0OU Distinguished name of the Tier 0 OU, e.g. OU=Tier 0,OU=Admin,DC=contoso,DC=com. .PARAMETER GroupName Name of the delegation group. Default: Tier0-Admins. .PARAMETER GroupOU Where to create the group. Defaults to OU=Groups under the Tier 0 OU, falling back to the Tier 0 OU itself. .PARAMETER Member Accounts to add to the group (sAMAccountName or DN). Use dedicated admin accounts, not daily-driver ones. .PARAMETER Server Domain or domain controller to talk to. Defaults to the domain of the computer you're running on. .EXAMPLE .\Grant-Tier0Delegation.ps1 -Tier0OU 'OU=Tier 0,OU=Admin,DC=contoso,DC=com' -WhatIf .EXAMPLE .\Grant-Tier0Delegation.ps1 -Tier0OU 'OU=Tier 0,OU=Admin,DC=contoso,DC=com' -Member adm-t0-jdoe, adm-t0-asmith #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)][ValidatePattern('^OU=.+DC=')][string]$Tier0OU, [ValidateNotNullOrEmpty()][string]$GroupName = 'Tier0-Admins', [string]$GroupOU, [string[]]$Member, [string]$Server ) $ErrorActionPreference = 'Stop' Import-Module ActiveDirectory $ad = @{} if ($Server) { $ad.Server = $Server } function Write-Result([string]$Action, [string]$Target, [string]$Result, [string]$Detail = '') { [pscustomobject]@{ Action = $Action; Target = $Target; Result = $Result; Detail = $Detail } } # --- Check the OU and decide where the group lives $null = Get-ADOrganizationalUnit -Identity $Tier0OU @ad if (-not $GroupOU) { $candidate = "OU=Groups,$Tier0OU" $GroupOU = if (Get-ADOrganizationalUnit -Filter * -SearchBase $Tier0OU -SearchScope OneLevel @ad | Where-Object DistinguishedName -eq $candidate) { $candidate } else { $Tier0OU } } if ($GroupOU -notlike "*$Tier0OU") { Write-Warning "$GroupOU is outside $Tier0OU. Whoever controls that OU can add themselves to your Tier 0 group." } # --- 1. The group $group = Get-ADGroup -Filter "Name -eq '$($GroupName -replace "'", "''")'" @ad if ($group) { Write-Result 'Create group' $GroupName 'Skipped' "Already exists at $($group.DistinguishedName)" } elseif ($PSCmdlet.ShouldProcess("$GroupName in $GroupOU", 'Create security group')) { $group = New-ADGroup -Name $GroupName -SamAccountName $GroupName -GroupCategory Security -GroupScope Global -Path $GroupOU -Description "Full control of $Tier0OU (tiered admin model)" -PassThru @ad Write-Result 'Create group' $GroupName 'Done' } else { Write-Result 'Create group' $GroupName 'WhatIf' } # --- 2. Members foreach ($m in $Member) { if (-not $group) { Write-Result 'Add member' $m 'WhatIf' 'Group would be created first'; continue } try { if ($PSCmdlet.ShouldProcess($GroupName, "Add member $m")) { Add-ADGroupMember -Identity $group -Members $m @ad Write-Result 'Add member' $m 'Done' } else { Write-Result 'Add member' $m 'WhatIf' } } catch { Write-Result 'Add member' $m 'Failed' $_.Exception.Message } } # --- 3. Delegate Full Control on the Tier 0 OU, inherited by everything below it if (-not $group) { Write-Result 'Delegate Full Control' $Tier0OU 'WhatIf' 'Group would be created first' return } $sid = [System.Security.Principal.SecurityIdentifier]$group.SID.Value $ou = Get-ADObject -Identity $Tier0OU -Properties nTSecurityDescriptor @ad $acl = $ou.nTSecurityDescriptor $full = [System.DirectoryServices.ActiveDirectoryRights]::GenericAll $have = $acl.GetAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier]) | Where-Object { $_.IdentityReference -eq $sid -and ($_.ActiveDirectoryRights -band $full) -eq $full -and $_.InheritanceType -eq 'All' } if ($have) { Write-Result 'Delegate Full Control' $Tier0OU 'Skipped' 'Permission already present' } elseif ($PSCmdlet.ShouldProcess($Tier0OU, "Grant $GroupName Full Control (this OU and all descendants)")) { $rule = [System.DirectoryServices.ActiveDirectoryAccessRule]::new($sid, 'GenericAll', 'Allow', [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All) $acl.AddAccessRule($rule) Set-ADObject -Identity $Tier0OU -Replace @{ nTSecurityDescriptor = $acl } @ad Write-Result 'Delegate Full Control' $Tier0OU 'Done' } else { Write-Result 'Delegate Full Control' $Tier0OU 'WhatIf' }