Set-GroupToSecure.ps1
<#PSScriptInfo .VERSION 2.0 .GUID cb08b379-374f-4ee7-8f88-3c0f57fc7c52 .AUTHOR Peter Remstad .COMPANYNAME .COPYRIGHT All rights reserved. .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 available. #> Param() # RESETS SCRIPT VARIABLES $GroupName = $null $TemplateACL = $null $DomainCheck = $null $GroupCheck = $null # RECEIVES USER INPUTS $DomainName = Read-Host "Input full domain name" $GroupName = Read-Host "Input name of group to secure" # GETS DA CREDENTIALS $Creds = Get-Credential -Message "Input Domain Admin credentials for $DomainName." # IMPORTS AD MODULE If (Get-Module -ListAvailable | Where {$_.Name -eq "ActiveDirectory"}) { Import-Module ActiveDirectory } Else { Write-Error -Message "ActiveDirectory PowerShell module not found." Break } # CHECKS WHETHER THE PROVIDED DOMAIN NAME IS REACHABLE AND IF GROUP EXISTS $ErrorActionPreference = "silentlyContinue" $DomainCheck = Get-ADDomain -Server $DomainName $GroupCheck = Get-ADGroup -Identity $GroupName -Properties Description -Credential $Creds $ErrorActionPreference = "Continue" # THROWS ERROR IF DOMAIN IS UNREACHABLE If ($DomainCheck -eq $null) { Write-Error -Message "Domain $DomainName could not be found. Please check spelling and try again." } Else { Write-Host -ForegroundColor Cyan "Domain $DomainName found!" } # 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 $DomainName. Terminating script." } Else { Write-Host -ForegroundColor Cyan "Group $GroupName located in $DomainName!" Write-Host -ForegroundColor Cyan "Proceeding with group lockdown..." } # CREATES SCRIPTBLOCK FOR USE WITH INVOKE-COMMAND SO CREDENTIALS CAN BE PASSED FOR ALL INTERNAL COMMANDS $ScriptBlock = [scriptblock]::Create({ param ( $Group, $DomainInfo ) $Error.Clear() # 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: # 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!" } }) # EXECUTES SCRIPTBLOCK SO THAT GET-ACL AND SET-ACL CAN BE RUN UNDER PROVIDED CREDENTIALS Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $GroupCheck,$DomainCheck -ComputerName $DomainCheck.PDCEmulator -Credential $Creds # 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 } |