read
The use case i needed to solve looked like this:
- A group policy to enforce some behaviour in the environment already exists; lets say - GPO to apply a default wallpaper.
- I want to allow exceptions to the GPO via Pull Request on a Github repo
- (The reason for this approach: removes the need to let lots of people near gpmc; instead we just use a PR with an approval workflow tied to it)
Because i am looking to exclude computers from applying GPO i’ll need to set a DENY on the “Apply Group Policy” extended right: https://docs.microsoft.com/en-us/windows/win32/adschema/r-apply-group-policy
exceptions.json
:
[
{
computername: "bob-machine1",
expires:"1/1/2022"
},
{
computername: "bob-machine2",
expires:"1/1/2022"
}
]
worker.ps1
:
$EXCEPTIONS_FILE = "c:\automation\repo-name\exceptions.json"
$TARGET_GPO_GUID = "bd782ff6-907e-4346-8452-1751957cb35e"
$DOMAIN_DN = "DC=testdomain,DC=local"
# Import the exceptions list from the JSON input:
$Exceptions = Get-Content -Raw -Path $EXCEPTIONS_FILE | ConvertFrom-Json
# Safety first:
if ($Exceptions.Count -lt 1 -or $Exceptions.Count -gt 100)
{
$ExCount = $Exceptions.Count
Write-Error "Number of exceptions is out of acceptable range. Count was $ExCount"
Exit(1)
}
# Adjust the group policy ACL
ForEach ($ComputerEntry in $Exceptions)
{
$computer = get-adcomputer $ComputerEntry.computername
$computer_SID = [System.Security.Principal.SecurityIdentifier] $computer.SID
$computer_identity = [System.Security.Principal.IdentityReference] $computer_SID
$GPO = Get-GPO -Guid $TARGET_GPO_GUID
$GPO_ADSI = [ADSI]"LDAP://CN=`{$($GPO.Id)`},CN=Policies,CN=System,$DOMAIN_DN"
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$computer_identity,
"ExtendedRight",
"Deny",
[Guid]"edacfd8f-ffb3-11d1-b41d-00a0c968f939" # Apply GPO Extended Right. https://docs.microsoft.com/en-us/windows/win32/adschema/r-apply-group-policy
)
$ACL = $GPO_ADSI.ObjectSecurity
$ACL.AddAccessRule($ACE)
$GPO_ADSI.CommitChanges()
}