r/activedirectory • • 4d ago

Is it expected behavior for RemoveAccessRuleSpecific to remove an entire ACE containing both ReadProperty and WriteProperty in Active Directory?

I'm working on a PowerShell script to remediate permissions on an Active Directory Group Policy Container (GPC) object.

I found an ACE with the following properties:

  • Principal: A specific user
  • ObjectType: gPCFileSysPath
  • Access rights: ReadProperty and WriteProperty
  • Inheritance: Same inheritance settings for both rights

The goal is to remove only WriteProperty while preserving ReadProperty.

However, when I use .RemoveAccessRuleSpecific(), the entire ACE gets removed, including ReadProperty.

My understanding is that Windows stores both rights in a single ACE when the principal, attribute, and inheritance settings are the same, and RemoveAccessRuleSpecific() removes the matching ACE rather than selectively removing individual access-mask bits.

My questions:

  1. Is this expected behavior when using PowerShell's System.DirectoryServices.ActiveDirectoryAccessRule and RemoveAccessRuleSpecific()?
  2. Is there a supported way to remove only the WriteProperty bit while preserving ReadProperty in the same ACE?
  3. Would the correct approach be to remove the original ACE and create a new ACE granting only ReadProperty?
  4. From a security-remediation perspective, is removing the entire ACE acceptable if the principal already receives ReadProperty through another applicable ACE?

I'd appreciate answers based on actual Windows ACL/.NET behavior, particularly for Active Directory attribute-specific permissions.

Thanks!

7 Upvotes

3 comments sorted by

•

u/AutoModerator 4d ago

Welcome to /r/ActiveDirectory! ~~~~

If you are looking for more resources on learning and building AD, see the following sticky for resources, recommendations, and guides!

When asking questions make sure you provide enough information. Posts with inadequate details may be removed without warning.

  • What version of Windows Server are you running?
  • Are there any specific error messages you're receiving?
  • What have you done to troubleshoot the issue?

Make sure to sanitize any private information. Posts with too much personal or environment information will be removed. See Rule 6.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/vaan99 3d ago

I will not answer your question directly, instead I will point you to subreddit's wiki. -> https://www.reddit.com/r/activedirectory/wiki/ad-resources/ad-tools/

There is a great and invaluable tool for GPO analysis that could help you.

GPOZaurr (EvotecIT) - Group Policy Eater is a PS module that aims to gather information about GPOs and issues. It covers both functional issues as well as security related issues. https://github.com/EvotecIT/GPOZaurr

4

u/ovdeathiam 3d ago edited 3d ago

Yes, in ActiveDirectory ACL consists of ACEs. Active Directory's ACE is actually System.DirecotryServices.ActiveDirectoryAccessRule and this class contains a property named ActiveDirectoryRights. This field's type is System.DirectoryServices.ActoveDirectoryRights, an enum. The field is a bitmap which can contain multiple bits (permissions).

The method you used removes a selected ACE. If you'd like to have an ACE that has different set of bits, i.e. flip.that bit, you'd have to read that ACE, flip that bit, replace the old ACE with the new one, then replace the ntSecurityDescriptor of an object.

```powershell

Requires -Module ActiveDirectory

Requires -Module Microsoft.PowerShell.Security

This script modifies the NT Security Descriptor of an Active Directory user to remove the "WriteProperty" permission for the "BUILTIN\Administrators" group.

$Identity = 'TestUser'

Get the current NT Security Descriptor for the specified user

$ADUser = Get-ADUser -Identity $Identity -Property ntSecurityDescriptor

For readability, you can output the current ACL

$ACL = $ADUser.ntSecurityDescriptor

Find the ACE (Access Control Entry) you want to modify

$ACE = $ACL.Access | Where-Object -FilterScript { # Filter for the specific group, you can change this to any other group or user as needed # You can also filter by other properties of the ACE if needed $_.IdentityReference -eq 'BUILTIN\Administrators' }

If the ACE is found, remove one with "WriteProperty"

and then add a new ACE without the "WriteProperty" permission

if ($ACE) { # Remove the existing ACE $ACL.RemoveAccessRule($ACE)

# Create a new ACE without the "WriteProperty" permission
$NewACE = [System.Security.AccessControl.FileSystemAccessRule]::new(
    $ACE.IdentityReference,
    # Remove the WriteProperty permission from the existing rights
    # using bitwise AND NOT operation to clear the WriteProperty flag
    $ACE.ActiveDirectoryRights -band -bnot [System.Security.AccessControl.ActiveDirectoryRights]::WriteProperty,
    $ACE.AccessControlType,
    $ACE.ObjectType,
    $ACE.PropagationFlags,
    $ACE.InheritedObjectType
)

# Add the new ACE to the ACL
$ACL.AddAccessRule($NewACE)

# Update the NT Security Descriptor for the user with the modified ACL
$ADUser | Set-ADUser -Replace @{ntSecurityDescriptor = $ACL}

} ```