From cd788c76935fda73ae2e821a0f444b5ba8f321a7 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 21 Oct 2026 12:13:51 +0000 Subject: [PATCH] test(access): pin the ReadSecurityError category of Get-NTFSAccess after a failed ownership retry Get-NTFSAccess writes ReadSecurityError with category WriteError when a read succeeds only after the cmdlet takes ownership and the restored owner is irrelevant to that path; Get-NTFSAudit, Get-NTFSEffectiveAccess, Get-NTFSInheritance, and Get-NTFSSecurityDescriptor already report the same failure the same way, so this is the module's convention, unlike Get-NTFSOrphanedAccess, whose own category for the same failure is ReadError. No script could notice: the behavior does not change. A characterization test in Tests\ParameterSets.Access.Tests.ps1, next to the orphaned-access test that already pins the ReadError side of the same convention, is green at once and runs in all four configurations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant --- Tests/ParameterSets.Access.Tests.ps1 | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Tests/ParameterSets.Access.Tests.ps1 b/Tests/ParameterSets.Access.Tests.ps1 index 551cc3b..bea7643 100644 --- a/Tests/ParameterSets.Access.Tests.ps1 +++ b/Tests/ParameterSets.Access.Tests.ps1 @@ -911,6 +911,37 @@ Describe 'Get-NTFSAccess' { @($piped | Where-Object -FilterScript { $_.FullName -eq $file2 }) | Should -HaveCount $expectedSecond } } + + Context 'Path parameter set, unreadable folder' { + BeforeAll { + # Forcing EnablePrivileges off reproduces the same denial as a basic user for an elevated session, as + # PathErrors.Tests.ps1 does for the same scenario, and as the Get-NTFSOrphanedAccess test below does. + $privateData['EnablePrivileges'] = $false + } + + AfterAll { + $privateData['EnablePrivileges'] = $enablePrivileges + } + + # Get-NTFSAccess, Get-NTFSAudit, Get-NTFSEffectiveAccess, Get-NTFSInheritance, and Get-NTFSSecurityDescriptor + # all report a failed ownership retry as ReadSecurityError categorized as WriteError (GetAccess.cs); this is + # the module's convention. A characterization test: the behavior is already correct, only not yet pinned for + # this cmdlet (6a). Unlike Get-NTFSOrphanedAccess, whose own category for the same failure is ReadError. + It 'Should write a ReadSecurityError categorized as WriteError after a failed ownership retry, and still return the next path''s entries' { + $blocked = New-TestSandboxItem -Sandbox $sandbox -Name 'GetAccessUnreadable' + Block-TestReadPermission -Sandbox $sandbox -Path $blocked + $next = New-TestSandboxItem -Sandbox $sandbox -Name 'GetAccessUnreadableNext' + Add-NTFSAccess -Path $next -Account 'S-1-1-0' -AccessRights ReadData -ErrorAction Stop + + $result = @(Get-NTFSAccess -Path $blocked, $next -ErrorVariable accessErrors -ErrorAction SilentlyContinue) + + $accessErrors | Should -HaveCount 1 + $accessErrors[0].FullyQualifiedErrorId | Should -BeLike 'ReadSecurityError,*' + $accessErrors[0].CategoryInfo.Category | Should -Be 'WriteError' + $accessErrors[0].TargetObject | Should -Be $blocked + @($result | Where-Object -FilterScript { $_.FullName -eq $next -and $_.Account.Sid -eq 'S-1-1-0' -and -not $_.IsInherited }) | Should -HaveCount 1 + } + } } Describe 'Get-NTFSOrphanedAccess' {