From 8247c85fc1f5d29cac7655b484f4e3dc94329e66 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Thu, 8 Oct 2026 11:54:06 +0000 Subject: [PATCH] test: cover -PassThru and the flag parameters of Add-NTFSAccess The coverage report of rc6 showed parameters that no test used: -PassThru after a successful change in both parameter sets, -InheritanceFlags and -PropagationFlags on a folder and on a file, where the page says they are ignored, and Clear-NTFSAccess -DisableInheritance on a security descriptor. The tests pin the documented behavior; all pass in the four configurations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant --- Tests/Access.Tests.ps1 | 59 ++++++++++++++++++++++++++ Tests/SecurityDescriptorSets.Tests.ps1 | 18 ++++++++ 2 files changed, 77 insertions(+) diff --git a/Tests/Access.Tests.ps1 b/Tests/Access.Tests.ps1 index 6c34196..097ffcc 100644 --- a/Tests/Access.Tests.ps1 +++ b/Tests/Access.Tests.ps1 @@ -635,6 +635,65 @@ Describe 'Add-NTFSAccess' { @($acl.GetAccessRules($false, $true, $sidType)) | Should -HaveCount $inheritedCount } } + + # The page: -PassThru writes all entries, explicit and inherited, of every item that the cmdlet changed. + Context 'With -PassThru' { + It 'Should write all entries of the item after the change' { + $file = New-TestSandboxItem -Sandbox $sandbox -Name 'AddPassThru' + Assert-TestSandboxPath -Sandbox $sandbox -Path $file + + $result = @(Add-NTFSAccess -Path $file -Account 'S-1-1-0' -AccessRights ReadData -PassThru) + + $result | ForEach-Object -Process { $_ | Should -BeOfType [Security2.FileSystemAccessRule2] } + $result | Should -HaveCount @(Get-NTFSAccess -Path $file).Count + @($result | Where-Object -FilterScript { $_.IsInherited }) | Should -Not -BeNullOrEmpty + $added = @($result | Where-Object -FilterScript { $_.Account.Sid -eq 'S-1-1-0' -and -not $_.IsInherited }) + $added | Should -HaveCount 1 + $added[0].AccessRights.HasFlag([Security2.FileSystemRights2]::ReadData) | Should -BeTrue + } + + It 'Should write all entries of a security descriptor after the change and leave the item unchanged' { + $file = New-TestSandboxItem -Sandbox $sandbox -Name 'AddPassThruDescriptor' + Assert-TestSandboxPath -Sandbox $sandbox -Path $file + $sd = Get-NTFSSecurityDescriptor -Path $file + + $result = @(Add-NTFSAccess -SecurityDescriptor $sd -Account 'S-1-1-0' -AccessRights ReadData -PassThru) + + $result | Should -HaveCount @($sd.SecurityDescriptor.GetAccessRules($true, $true, $sidType)).Count + @($result | Where-Object -FilterScript { $_.Account.Sid -eq 'S-1-1-0' -and -not $_.IsInherited }) | Should -HaveCount 1 + @((Get-Acl -LiteralPath $file).GetAccessRules($true, $false, $sidType) | + Where-Object -FilterScript { $_.IdentityReference.Value -eq 'S-1-1-0' }) | Should -BeNullOrEmpty + } + } + + Context 'With -InheritanceFlags and -PropagationFlags' { + It 'Should add an entry with the flags to a folder' { + $folder = New-TestSandboxItem -Sandbox $sandbox -Name 'AddFlags' -Directory + Assert-TestSandboxPath -Sandbox $sandbox -Path $folder + + Add-NTFSAccess -Path $folder -Account 'S-1-5-32-546' -AccessRights ReadData -InheritanceFlags ContainerInherit -PropagationFlags InheritOnly + + $rules = @((Get-Acl -LiteralPath $folder).GetAccessRules($true, $false, $sidType) | + Where-Object -FilterScript { $_.IdentityReference.Value -eq 'S-1-5-32-546' }) + $rules | Should -HaveCount 1 + $rules[0].InheritanceFlags | Should -Be ([System.Security.AccessControl.InheritanceFlags]::ContainerInherit) + $rules[0].PropagationFlags | Should -Be ([System.Security.AccessControl.PropagationFlags]::InheritOnly) + } + + # The page: inheritance and propagation flags are ignored on files. + It 'Should add an entry without flags to a file' { + $file = New-TestSandboxItem -Sandbox $sandbox -Name 'AddFlagsFile' + Assert-TestSandboxPath -Sandbox $sandbox -Path $file + + Add-NTFSAccess -Path $file -Account 'S-1-5-32-546' -AccessRights ReadData -InheritanceFlags 'ContainerInherit, ObjectInherit' -PropagationFlags InheritOnly + + $rules = @((Get-Acl -LiteralPath $file).GetAccessRules($true, $false, $sidType) | + Where-Object -FilterScript { $_.IdentityReference.Value -eq 'S-1-5-32-546' }) + $rules | Should -HaveCount 1 + $rules[0].InheritanceFlags | Should -Be ([System.Security.AccessControl.InheritanceFlags]::None) + $rules[0].PropagationFlags | Should -Be ([System.Security.AccessControl.PropagationFlags]::None) + } + } } Describe 'Security descriptor parameter sets' { diff --git a/Tests/SecurityDescriptorSets.Tests.ps1 b/Tests/SecurityDescriptorSets.Tests.ps1 index a8d4a8a..fcd15e1 100644 --- a/Tests/SecurityDescriptorSets.Tests.ps1 +++ b/Tests/SecurityDescriptorSets.Tests.ps1 @@ -50,6 +50,24 @@ Describe 'Cmdlets that change a security descriptor in memory' { Get-ExplicitAccessCount -Acl (Get-Acl -LiteralPath $file) | Should -Be 0 } + # Like the Path parameter set, the cmdlet doesn't copy the inherited entries, so the DACL ends up empty. + It 'Clear-NTFSAccess -DisableInheritance should leave the descriptor with an empty, protected DACL' { + $file = New-TestSandboxItem -Sandbox $sandbox -Name 'ClearAccessProtected' + Add-NTFSAccess -Path $file -Account 'S-1-1-0' -AccessRights ReadData + $daclBefore = (Get-Acl -LiteralPath $file).GetSecurityDescriptorSddlForm('Access') + $sd = Get-NTFSSecurityDescriptor -Path $file + + Clear-NTFSAccess -SecurityDescriptor $sd -DisableInheritance -ErrorAction Stop + + $sd.SecurityDescriptor.AreAccessRulesProtected | Should -BeTrue + @($sd.SecurityDescriptor.GetAccessRules($true, $true, $sidType)) | Should -BeNullOrEmpty + (Get-Acl -LiteralPath $file).GetSecurityDescriptorSddlForm('Access') | Should -Be $daclBefore + Set-NTFSSecurityDescriptor -SecurityDescriptor $sd -ErrorAction Stop + $acl = Get-Acl -LiteralPath $file + $acl.AreAccessRulesProtected | Should -BeTrue + @($acl.GetAccessRules($true, $true, $sidType)) | Should -BeNullOrEmpty + } + It 'Disable-NTFSAccessInheritance should protect the DACL of the descriptor and keep the inherited entries' { $file = New-TestSandboxItem -Sandbox $sandbox -Name 'DisableAccess' $inheritedCount = @((Get-Acl -LiteralPath $file).GetAccessRules($false, $true, $sidType)).Count