Set-GroupToSecure.ps1
<#PSScriptInfo .VERSION 1.0 .GUID 7fafd626-c029-4fcb-93f8-b42652d0635e .AUTHOR Peter Remstad .COMPANYNAME .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION Modifies an Active Directory Group's ACL to match 'ADMINSDHOLDER' to effectively lockdown the group, disabling inheritance, so only Domain Admins and Enterprise Admins can modify membership. This helps secure high risk custom RBAC groups such as a 'Server Admins' group. NOTE - Requires ActiveDirectory module to be installed on the system executing the script. Also requires the executer of the script to have Domain Admin credentials. #> Param() ############################################################################################ # Script Name: Set-GroupToSecure.ps1 # Current Version: 1.0 # Written By: Peter Remstad # Date Created: 2020-08-11 # # Notes: v1.0 - This script modifies the ACL on an AD Group to match AdminSDHolder. This # will mean that inheritance is blocked and only DA/EA's can modify the # group membership. Helps secure custom critical RBAC groups. # ############################################################################################ # RESETS SCRIPT VARIABLES $GroupName = $null $TemplateACL = $null $GroupCheck = $null # GETS DA CREDENTIALS $Creds = Get-Credential -Message "Input Domain Admin credentials" # IMPORTS AD MODULE Import-Module ActiveDirectory # RECEIVES GROUP INPUT $GroupName = Read-Host "Input name of group to secure" # CHECKS WHETHER THE PROVIDED INPUT EXISTS $ErrorActionPreference = "silentlyContinue" $GroupCheck = Get-ADGroup -Identity $GroupName -Properties Description -Credential $Creds $ErrorActionPreference = "Continue" # THROWS ERROR IF GROUP DOESN'T EXIST, OTHERWISE EXECUTES GROUP ACL CHANGE If ($GroupCheck -eq $null) { Write-Error -Message "Group $GroupName could not be found in Active Directory. Terminating script." } Else { Write-Host -ForegroundColor Cyan "Group $GroupName located! Proceeding with group lockdown..." $Domain = Get-ADDomain # CREATES SCRIPTBLOCK FOR USE WITH INVOKE-COMMAND SO CREDENTIALS CAN BE PASSED FOR ALL INTERNAL COMMANDS $ScriptBlock = [scriptblock]::Create({ param ( $Group, $DomainInfo ) # IMPORTS AD MODULE AND CHANGES TO AD DRIVE Import-Module ActiveDirectory Set-Location -Path AD: # GETS ADMINSDHOLDER ACL $TemplateACL = Get-Acl -Path "CN=AdminSDHolder,CN=System,$($DomainInfo.DistinguishedName)" # APPLIES ACL TO TARGET GROUP AND CHANGES BACK TO C DRIVE Set-Acl -Path $Group.DistinguishedName -AclObject $TemplateACL -Confirm:$false Set-Location -Path C: }) $Error.Clear() # EXECUTES SCRIPTBLOCK SO THAT GET-ACL AND SET-ACL CAN BE RUN UNDER PROVIDED CREDENTIALS Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $GroupCheck,$Domain -ComputerName $env:COMPUTERNAME -Credential $Creds # SETS ADMINCOUNT AND APPENDS DESCRIPTION TO GROUP Set-ADObject -Identity $GroupCheck.DistinguishedName -Add @{AdminCount=1} -Description "$($GroupCheck.Description)-GroupLockedDown" -Credential $Creds If ($Error.count -ne 0) { Write-Host -ForegroundColor Red "Lockdown commands returned errors. Manually validate group." } Else { Write-Host -ForegroundColor Cyan "Group lockdown completed!" } } # WAITS TO CLOSE WINDOW UNTIL A KEY PRESS If ($Host.Name -eq "ConsoleHost") { Write-Host "" Write-Host "Press any key to continue..." $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp") > $null } |