Browse Source

feat!: keep entries in Set-NTFSInheritance like the dedicated cmdlets

-AccessInheritanceEnabled $false now copies the inherited access entries
into the DACL, and -AuditInheritanceEnabled $true keeps the explicit audit
entries, as Disable-NTFSAccessInheritance and Enable-NTFSAuditInheritance
do without their switches (Decision 13).

BREAKING CHANGE: to remove the entries, use
Disable-NTFSAccessInheritance -RemoveInheritedAccessRules or
Enable-NTFSAuditInheritance -RemoveExplicitAuditRules.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
pull/104/head
Raimund Andree 7 days ago
parent
commit
437d353c8f
  1. 34
      .memory-bank/decisions/0013-set-inheritance-keeps-entries.md
  2. 1
      .memory-bank/systemPatterns.md
  3. 6
      CHANGELOG.md
  4. 10
      Docs/Cmdlets/Set-NTFSInheritance.md
  5. 10
      Docs/Concepts.md
  6. 8
      NTFSSecurity/InheritanceCmdlets/SetInheritance.cs
  7. 18
      NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
  8. 39
      Tests/Inheritance.Tests.ps1

34
.memory-bank/decisions/0013-set-inheritance-keeps-entries.md

@ -0,0 +1,34 @@
---
status: accepted
date: 2026-10-05
last-verified: 2026-10-05
owner: shared
source: maintainer decision D3 for the overnight run of 2026-10-04 (defect group E)
---
# Decision 13: Set-NTFSInheritance keeps entries like the dedicated cmdlets
- Choice: `Set-NTFSInheritance` uses the defaults of the dedicated cmdlets.
`-AccessInheritanceEnabled $false` copies the inherited access entries
into the DACL, like `Disable-NTFSAccessInheritance`, and
`-AuditInheritanceEnabled $true` keeps the explicit audit entries, like
`Enable-NTFSAuditInheritance`. The other two directions already matched.
The same applies to a security descriptor in memory, whose kept entries
stay marked as inherited until it is written.
- Way back: `Disable-NTFSAccessInheritance -RemoveInheritedAccessRules`
removes the inherited access entries, and
`Enable-NTFSAuditInheritance -RemoveExplicitAuditRules` removes the
explicit audit entries. `Set-NTFSInheritance` gets no switches for that.
- Rationale: Before 5.0.0, two of the four directions removed entries,
unlike the dedicated cmdlets. Turning access inheritance off on an item
without explicit entries left an empty DACL, which denies access to
everyone. 5.0.0 is a major version, so the change ships there, listed
under `Changed` in the changelog.
- Related: `Clear-NTFSAccess -DisableInheritance` keeps discarding the
inherited entries, because removing every entry is the purpose of that
cmdlet; its page states the empty DACL and its risk (decision D2 of the
same run). The audit switches were renamed to `-RemoveInheritedAuditRules`
and `-RemoveExplicitAuditRules`, with the old names as aliases (D4).
- Rejected: adding `-RemoveInheritedAccessRules` and
`-RemoveExplicitAuditRules` switches to `Set-NTFSInheritance`, which would
duplicate the dedicated cmdlets.

1
.memory-bank/systemPatterns.md

@ -58,6 +58,7 @@ Each Decision record is a file in `decisions/`; read only the relevant ones.
| 10 | [One version for the manifest, assemblies, and changelog](decisions/0010-one-version.md) |
| 11 | [CI and the wiki run on GitHub Actions](decisions/0011-github-actions.md) |
| 12 | [Releases are built and published by CI on a version tag](decisions/0012-ci-releases.md) |
| 13 | [Set-NTFSInheritance keeps entries like the dedicated cmdlets](decisions/0013-set-inheritance-keeps-entries.md) |
## Patterns

6
CHANGELOG.md

@ -40,6 +40,12 @@ The format is based on
`-RemoveInheritedAuditRules` and `-RemoveExplicitAccessRules` of
`Enable-NTFSAuditInheritance` to `-RemoveExplicitAuditRules`, because they
act on audit entries; the old names still work as aliases
- `Set-NTFSInheritance` keeps entries like the dedicated cmdlets:
`-AccessInheritanceEnabled $false` now copies the inherited access entries
into the DACL instead of removing them, and
`-AuditInheritanceEnabled $true` now keeps the explicit audit entries. To
remove them, use `Disable-NTFSAccessInheritance -RemoveInheritedAccessRules`
or `Enable-NTFSAuditInheritance -RemoveExplicitAuditRules`
### Deprecated

10
Docs/Cmdlets/Set-NTFSInheritance.md

@ -29,7 +29,7 @@ Set-NTFSInheritance [-SecurityDescriptor] <FileSystemSecurity2[]> [-AccessInheri
The `Set-NTFSInheritance` cmdlet turns the inheritance of access rules and audit rules on or off in a single call. It reads the current state of the item first and changes a section only when the requested value differs from the current one, which makes the cmdlet suitable for repeatedly applying a desired state to a folder tree.
The cmdlet performs the same operations as `Enable-NTFSAccessInheritance`, `Disable-NTFSAccessInheritance`, `Enable-NTFSAuditInheritance`, and `Disable-NTFSAuditInheritance`, but it does not expose their switches and it does not use their defaults. `-AccessInheritanceEnabled $false` discards the inherited access rules instead of copying them into the item's own DACL, `-AccessInheritanceEnabled $true` keeps the explicit access rules, `-AuditInheritanceEnabled $false` copies the inherited audit rules into the item's own SACL, and `-AuditInheritanceEnabled $true` removes the explicit audit rules. Use the individual Enable and Disable cmdlets when you need the opposite behavior.
The cmdlet performs the same operations as `Enable-NTFSAccessInheritance`, `Disable-NTFSAccessInheritance`, `Enable-NTFSAuditInheritance`, and `Disable-NTFSAuditInheritance`, but it does not expose their switches; it uses their defaults instead. `-AccessInheritanceEnabled $false` copies the inherited access rules into the item's own DACL, `-AccessInheritanceEnabled $true` keeps the explicit access rules, `-AuditInheritanceEnabled $false` copies the inherited audit rules into the item's own SACL, and `-AuditInheritanceEnabled $true` keeps the explicit audit rules. To remove the rules instead, use `Disable-NTFSAccessInheritance -RemoveInheritedAccessRules` or `Enable-NTFSAuditInheritance -RemoveExplicitAuditRules`. Before 5.0.0, `-AccessInheritanceEnabled $false` discarded the inherited access rules, and `-AuditInheritanceEnabled $true` removed the explicit audit rules.
Omit `-AccessInheritanceEnabled` or `-AuditInheritanceEnabled` to leave that section unchanged. Changing the audit section requires the Security privilege and therefore an elevated session.
@ -43,7 +43,7 @@ In the `Path` parameter set the cmdlet writes each changed section back to disk
PS C:\> Set-NTFSInheritance -Path C:\Data\Projects -AccessInheritanceEnabled $false -AuditInheritanceEnabled $false
```
This command protects the DACL and the SACL of `C:\Data\Projects`. The inherited access rules are discarded, so make sure the folder has explicit access rules of its own; the inherited audit rules are copied into the folder's SACL. Changing the audit section requires an elevated session.
This command protects the DACL and the SACL of `C:\Data\Projects`. The inherited access and audit rules are copied into the folder's DACL and SACL, so the effective permissions and the auditing stay the same. Changing the audit section requires an elevated session.
### Example 2: Restore inheritance of both sections
@ -51,7 +51,7 @@ This command protects the DACL and the SACL of `C:\Data\Projects`. The inherited
PS C:\> Set-NTFSInheritance -Path C:\Data\Projects -AccessInheritanceEnabled $true -AuditInheritanceEnabled $true -PassThru
```
This command lets the folder inherit from `C:\Data` again. The explicit access rules are kept, the explicit audit rules are removed, and `-PassThru` returns the resulting state.
This command lets the folder inherit from `C:\Data` again. The explicit access and audit rules are kept, and `-PassThru` returns the resulting state.
### Example 3: Save a state and apply it again
@ -77,7 +77,7 @@ The first two commands read the security descriptor and change its inheritance i
### -AccessInheritanceEnabled
Specifies whether the item inherits access rules from its parent folder. `$true` removes the protection from the DACL and keeps the access rules that are stored directly on the item; `$false` protects the DACL and discards the rules the item currently inherits, which leaves only its explicit rules. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the access section is left unchanged.
Specifies whether the item inherits access rules from its parent folder. `$true` removes the protection from the DACL and keeps the access rules that are stored directly on the item; `$false` protects the DACL and copies the rules the item currently inherits into it, so the effective permissions stay the same. Before 5.0.0, `$false` discarded the inherited rules. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the access section is left unchanged.
```yaml
Type: Boolean
@ -93,7 +93,7 @@ Accept wildcard characters: False
### -AuditInheritanceEnabled
Specifies whether the item inherits audit rules from its parent folder. `$true` removes the protection from the SACL and removes the audit rules that are stored directly on the item; `$false` protects the SACL and copies the inherited audit rules into it. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the audit section is left unchanged. Reading and writing the audit section requires the Security privilege and therefore an elevated session.
Specifies whether the item inherits audit rules from its parent folder. `$true` removes the protection from the SACL and keeps the audit rules that are stored directly on the item (before 5.0.0, it removed them); `$false` protects the SACL and copies the inherited audit rules into it. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the audit section is left unchanged. Reading and writing the audit section requires the Security privilege and therefore an elevated session.
```yaml
Type: Boolean

10
Docs/Concepts.md

@ -126,11 +126,13 @@ entries:
- `Enable-NTFSAccessInheritance` restores inheritance and keeps the explicit
entries unless you use `-RemoveExplicitAccessRules`.
- `Get-NTFSInheritance` and `Set-NTFSInheritance` read and set both
settings at once. Unlike the dedicated cmdlets, `Set-NTFSInheritance`
removes the inherited access entries when it turns access inheritance off,
and removes the explicit audit entries when it turns audit inheritance on.
settings at once. Like the dedicated cmdlets without their switches,
`Set-NTFSInheritance` keeps the entries; before 5.0.0, it removed the
inherited access entries when it turned access inheritance off, and the
explicit audit entries when it turned audit inheritance on.
The audit equivalents of the dedicated cmdlets are
`Disable-NTFSAuditInheritance` and `Enable-NTFSAuditInheritance`.
`Disable-NTFSAuditInheritance` and `Enable-NTFSAuditInheritance`, with
the switches `-RemoveInheritedAuditRules` and `-RemoveExplicitAuditRules`.
### The AppliesTo parameter

8
NTFSSecurity/InheritanceCmdlets/SetInheritance.cs

@ -142,7 +142,7 @@ namespace NTFSSecurity
else
{
WriteVerbose("Calling DisableAccessInheritance");
FileSystemInheritanceInfo.DisableAccessInheritance(item, true);
FileSystemInheritanceInfo.DisableAccessInheritance(item, false);
}
}
@ -151,7 +151,7 @@ namespace NTFSSecurity
if (auditInheritanceEnabled.Value)
{
WriteVerbose("Calling EnableAuditInheritance");
FileSystemInheritanceInfo.EnableAuditInheritance(item, true);
FileSystemInheritanceInfo.EnableAuditInheritance(item, false);
}
else
{
@ -175,7 +175,7 @@ namespace NTFSSecurity
else
{
WriteVerbose("Calling DisableAccessInheritance");
FileSystemInheritanceInfo.DisableAccessInheritance(sd, true);
FileSystemInheritanceInfo.DisableAccessInheritance(sd, false);
}
}
@ -184,7 +184,7 @@ namespace NTFSSecurity
if (auditInheritanceEnabled.Value)
{
WriteVerbose("Calling EnableAuditInheritance");
FileSystemInheritanceInfo.EnableAuditInheritance(sd, true);
FileSystemInheritanceInfo.EnableAuditInheritance(sd, false);
}
else
{

18
NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml

@ -9334,7 +9334,7 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
</command:details>
<maml:description>
<maml:para>The `Set-NTFSInheritance` cmdlet turns the inheritance of access rules and audit rules on or off in a single call. It reads the current state of the item first and changes a section only when the requested value differs from the current one, which makes the cmdlet suitable for repeatedly applying a desired state to a folder tree.</maml:para>
<maml:para>The cmdlet performs the same operations as `Enable-NTFSAccessInheritance`, `Disable-NTFSAccessInheritance`, `Enable-NTFSAuditInheritance`, and `Disable-NTFSAuditInheritance`, but it does not expose their switches and it does not use their defaults. `-AccessInheritanceEnabled $false` discards the inherited access rules instead of copying them into the item's own DACL, `-AccessInheritanceEnabled $true` keeps the explicit access rules, `-AuditInheritanceEnabled $false` copies the inherited audit rules into the item's own SACL, and `-AuditInheritanceEnabled $true` removes the explicit audit rules. Use the individual Enable and Disable cmdlets when you need the opposite behavior.</maml:para>
<maml:para>The cmdlet performs the same operations as `Enable-NTFSAccessInheritance`, `Disable-NTFSAccessInheritance`, `Enable-NTFSAuditInheritance`, and `Disable-NTFSAuditInheritance`, but it does not expose their switches; it uses their defaults instead. `-AccessInheritanceEnabled $false` copies the inherited access rules into the item's own DACL, `-AccessInheritanceEnabled $true` keeps the explicit access rules, `-AuditInheritanceEnabled $false` copies the inherited audit rules into the item's own SACL, and `-AuditInheritanceEnabled $true` keeps the explicit audit rules. To remove the rules instead, use `Disable-NTFSAccessInheritance -RemoveInheritedAccessRules` or `Enable-NTFSAuditInheritance -RemoveExplicitAuditRules`. Before 5.0.0, `-AccessInheritanceEnabled $false` discarded the inherited access rules, and `-AuditInheritanceEnabled $true` removed the explicit audit rules.</maml:para>
<maml:para>Omit `-AccessInheritanceEnabled` or `-AuditInheritanceEnabled` to leave that section unchanged. Changing the audit section requires the Security privilege and therefore an elevated session.</maml:para>
<maml:para>In the `Path` parameter set the cmdlet writes each changed section back to disk immediately. In the `SecurityDescriptor` parameter set it changes the `Security2.FileSystemSecurity2` object in memory only; nothing reaches the file system until you pass that object to `Set-NTFSSecurityDescriptor`. `-Path`, `-AccessInheritanceEnabled`, and `-AuditInheritanceEnabled` all accept pipeline input by property name, so a `Security2.FileSystemInheritanceInfo` object from `Get-NTFSInheritance` binds to all three at once.</maml:para>
</maml:description>
@ -9356,7 +9356,7 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="True (ByPropertyName)" position="named" aliases="none">
<maml:name>AccessInheritanceEnabled</maml:name>
<maml:description>
<maml:para>Specifies whether the item inherits access rules from its parent folder. `$true` removes the protection from the DACL and keeps the access rules that are stored directly on the item; `$false` protects the DACL and discards the rules the item currently inherits, which leaves only its explicit rules. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the access section is left unchanged.</maml:para>
<maml:para>Specifies whether the item inherits access rules from its parent folder. `$true` removes the protection from the DACL and keeps the access rules that are stored directly on the item; `$false` protects the DACL and copies the rules the item currently inherits into it, so the effective permissions stay the same. Before 5.0.0, `$false` discarded the inherited rules. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the access section is left unchanged.</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">Boolean</command:parameterValue>
<dev:type>
@ -9368,7 +9368,7 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="True (ByPropertyName)" position="named" aliases="none">
<maml:name>AuditInheritanceEnabled</maml:name>
<maml:description>
<maml:para>Specifies whether the item inherits audit rules from its parent folder. `$true` removes the protection from the SACL and removes the audit rules that are stored directly on the item; `$false` protects the SACL and copies the inherited audit rules into it. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the audit section is left unchanged. Reading and writing the audit section requires the Security privilege and therefore an elevated session.</maml:para>
<maml:para>Specifies whether the item inherits audit rules from its parent folder. `$true` removes the protection from the SACL and keeps the audit rules that are stored directly on the item (before 5.0.0, it removed them); `$false` protects the SACL and copies the inherited audit rules into it. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the audit section is left unchanged. Reading and writing the audit section requires the Security privilege and therefore an elevated session.</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">Boolean</command:parameterValue>
<dev:type>
@ -9408,7 +9408,7 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="True (ByPropertyName)" position="named" aliases="none">
<maml:name>AccessInheritanceEnabled</maml:name>
<maml:description>
<maml:para>Specifies whether the item inherits access rules from its parent folder. `$true` removes the protection from the DACL and keeps the access rules that are stored directly on the item; `$false` protects the DACL and discards the rules the item currently inherits, which leaves only its explicit rules. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the access section is left unchanged.</maml:para>
<maml:para>Specifies whether the item inherits access rules from its parent folder. `$true` removes the protection from the DACL and keeps the access rules that are stored directly on the item; `$false` protects the DACL and copies the rules the item currently inherits into it, so the effective permissions stay the same. Before 5.0.0, `$false` discarded the inherited rules. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the access section is left unchanged.</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">Boolean</command:parameterValue>
<dev:type>
@ -9420,7 +9420,7 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="True (ByPropertyName)" position="named" aliases="none">
<maml:name>AuditInheritanceEnabled</maml:name>
<maml:description>
<maml:para>Specifies whether the item inherits audit rules from its parent folder. `$true` removes the protection from the SACL and removes the audit rules that are stored directly on the item; `$false` protects the SACL and copies the inherited audit rules into it. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the audit section is left unchanged. Reading and writing the audit section requires the Security privilege and therefore an elevated session.</maml:para>
<maml:para>Specifies whether the item inherits audit rules from its parent folder. `$true` removes the protection from the SACL and keeps the audit rules that are stored directly on the item (before 5.0.0, it removed them); `$false` protects the SACL and copies the inherited audit rules into it. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the audit section is left unchanged. Reading and writing the audit section requires the Security privilege and therefore an elevated session.</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">Boolean</command:parameterValue>
<dev:type>
@ -9446,7 +9446,7 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="True (ByPropertyName)" position="named" aliases="none">
<maml:name>AccessInheritanceEnabled</maml:name>
<maml:description>
<maml:para>Specifies whether the item inherits access rules from its parent folder. `$true` removes the protection from the DACL and keeps the access rules that are stored directly on the item; `$false` protects the DACL and discards the rules the item currently inherits, which leaves only its explicit rules. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the access section is left unchanged.</maml:para>
<maml:para>Specifies whether the item inherits access rules from its parent folder. `$true` removes the protection from the DACL and keeps the access rules that are stored directly on the item; `$false` protects the DACL and copies the rules the item currently inherits into it, so the effective permissions stay the same. Before 5.0.0, `$false` discarded the inherited rules. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the access section is left unchanged.</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">Boolean</command:parameterValue>
<dev:type>
@ -9458,7 +9458,7 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="True (ByPropertyName)" position="named" aliases="none">
<maml:name>AuditInheritanceEnabled</maml:name>
<maml:description>
<maml:para>Specifies whether the item inherits audit rules from its parent folder. `$true` removes the protection from the SACL and removes the audit rules that are stored directly on the item; `$false` protects the SACL and copies the inherited audit rules into it. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the audit section is left unchanged. Reading and writing the audit section requires the Security privilege and therefore an elevated session.</maml:para>
<maml:para>Specifies whether the item inherits audit rules from its parent folder. `$true` removes the protection from the SACL and keeps the audit rules that are stored directly on the item (before 5.0.0, it removed them); `$false` protects the SACL and copies the inherited audit rules into it. The section is left untouched when the requested value already matches the current state. When you omit the parameter, the audit section is left unchanged. Reading and writing the audit section requires the Security privilege and therefore an elevated session.</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">Boolean</command:parameterValue>
<dev:type>
@ -9558,14 +9558,14 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
<maml:title>-------- Example 1: Block inheritance of both sections --------</maml:title>
<dev:code>PS C:\&gt; Set-NTFSInheritance -Path C:\Data\Projects -AccessInheritanceEnabled $false -AuditInheritanceEnabled $false</dev:code>
<dev:remarks>
<maml:para>This command protects the DACL and the SACL of `C:\Data\Projects`. The inherited access rules are discarded, so make sure the folder has explicit access rules of its own; the inherited audit rules are copied into the folder's SACL. Changing the audit section requires an elevated session.</maml:para>
<maml:para>This command protects the DACL and the SACL of `C:\Data\Projects`. The inherited access and audit rules are copied into the folder's DACL and SACL, so the effective permissions and the auditing stay the same. Changing the audit section requires an elevated session.</maml:para>
</dev:remarks>
</command:example>
<command:example>
<maml:title>------- Example 2: Restore inheritance of both sections -------</maml:title>
<dev:code>PS C:\&gt; Set-NTFSInheritance -Path C:\Data\Projects -AccessInheritanceEnabled $true -AuditInheritanceEnabled $true -PassThru</dev:code>
<dev:remarks>
<maml:para>This command lets the folder inherit from `C:\Data` again. The explicit access rules are kept, the explicit audit rules are removed, and `-PassThru` returns the resulting state.</maml:para>
<maml:para>This command lets the folder inherit from `C:\Data` again. The explicit access and audit rules are kept, and `-PassThru` returns the resulting state.</maml:para>
</dev:remarks>
</command:example>
<command:example>

39
Tests/Inheritance.Tests.ps1

@ -108,6 +108,45 @@ Describe 'Inheritance cmdlets with -PassThru' {
}
Describe 'Set-NTFSInheritance' {
Context 'When it changes the inheritance' {
# Before 5.0.0, -AccessInheritanceEnabled $false removed the inherited access entries and
# -AuditInheritanceEnabled $true removed the explicit audit entries, unlike the dedicated cmdlets.
It 'Should keep the inherited access entries as explicit ones when it disables access inheritance' {
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'KeepAccess'
Assert-TestSandboxPath -Sandbox $sandbox -Path $file
$inheritedCount = @((Get-Acl -LiteralPath $file).Access | Where-Object -Property IsInherited).Count
Set-NTFSInheritance -Path $file -AccessInheritanceEnabled $false
$acl = Get-Acl -LiteralPath $file
$acl.AreAccessRulesProtected | Should -BeTrue
@($acl.Access | Where-Object -Property IsInherited -EQ -Value $false) | Should -HaveCount $inheritedCount
}
# In memory, the kept entries stay marked as inherited; Windows stores them as explicit ones on write.
It 'Should keep the inherited access entries of a security descriptor' {
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'KeepDescriptor'
$sd = Get-NTFSSecurityDescriptor -Path $file
$sidType = [System.Security.Principal.SecurityIdentifier]
$inheritedCount = @($sd.SecurityDescriptor.GetAccessRules($false, $true, $sidType)).Count
Set-NTFSInheritance -SecurityDescriptor $sd -AccessInheritanceEnabled $false
$sd.SecurityDescriptor.AreAccessRulesProtected | Should -BeTrue
@($sd.SecurityDescriptor.GetAccessRules($true, $true, $sidType)) | Should -HaveCount $inheritedCount
}
It 'Should keep the explicit audit entries when it enables audit inheritance' -Skip:(-not $canChangeAudit) {
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'KeepAudit'
Assert-TestSandboxPath -Sandbox $sandbox -Path $file
Add-NTFSAudit -Path $file -Account 'Everyone' -AccessRights Delete -AuditFlags Failure
Disable-NTFSAuditInheritance -Path $file
Set-NTFSInheritance -Path $file -AuditInheritanceEnabled $true
@(Get-NTFSAudit -Path $file -ExcludeInherited) | Should -HaveCount 1
}
}
Context 'When -AccessInheritanceEnabled or -AuditInheritanceEnabled is omitted' {
BeforeEach {
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'File'

Loading…
Cancel
Save