diff --git a/Tests/Audit.Tests.ps1 b/Tests/Audit.Tests.ps1 index 1c58430..a9bc2ef 100644 --- a/Tests/Audit.Tests.ps1 +++ b/Tests/Audit.Tests.ps1 @@ -183,24 +183,92 @@ Describe 'Add-NTFSAudit' { Describe 'Get-NTFSOrphanedAudit' { BeforeAll { $orphanedFile = New-TestSandboxItem -Sandbox $sandbox -Name 'OrphanedAudit' + $missing = Join-Path -Path $sandbox -ChildPath 'MissingOrphanedAudit.txt' } - # Before 5.0.0, the cmdlet wrote the entries of an item as one collection and ignored -Account. - It 'Should return one object per entry whose account cannot be resolved' -Skip:(-not $canReadAudit) { - foreach ($sid in 'S-1-5-21-1-2-3-1001', 'S-1-5-21-1-2-3-1002') { - Add-NTFSAudit -Path $orphanedFile -Account $sid -AccessRights ReadData -InheritanceFlags None -PropagationFlags None + Context 'With the Security privilege' { + BeforeAll { + # Two entries of accounts that don't exist and one of Everyone, which resolves. Each test reads them, so + # none depends on another one. + foreach ($sid in 'S-1-5-21-1-2-3-1001', 'S-1-5-21-1-2-3-1002', 'S-1-1-0') { + Add-NTFSAudit -Path $orphanedFile -Account $sid -AccessRights ReadData -InheritanceFlags None -PropagationFlags None -ErrorAction Stop + } + + $orphanedFolder = New-TestSandboxItem -Sandbox $sandbox -Name 'OrphanedAuditFolder' -Directory + Add-NTFSAudit -Path $orphanedFolder -Account 'S-1-5-21-1-2-3-1003' -AccessRights Delete -ErrorAction Stop + $inheritingFile = Join-Path -Path $orphanedFolder -ChildPath 'File.txt' + Assert-TestSandboxPath -Sandbox $sandbox -Path $inheritingFile + Set-Content -LiteralPath $inheritingFile -Value 'File' + } + + # Before 5.0.0, the cmdlet wrote the entries of an item as one collection and ignored -Account. + It 'Should return one object per entry whose account cannot be resolved' -Skip:(-not $canReadAudit) { + $result = @(Get-NTFSOrphanedAudit -Path $orphanedFile) + + $result | Should -HaveCount 2 + $result | ForEach-Object -Process { $_ | Should -BeOfType [Security2.FileSystemAuditRule2] } + $result.Account.Sid | Should -Not -Contain 'S-1-1-0' + } + + It 'Should return only the entries of -Account' -Skip:(-not $canReadAudit) { + $result = @(Get-NTFSOrphanedAudit -Path $orphanedFile -Account 'S-1-5-21-1-2-3-1002') + + $result | Should -HaveCount 1 + $result[0].Account.Sid | Should -Be 'S-1-5-21-1-2-3-1002' + } + + It 'Should read the entries of a security descriptor' -Skip:(-not $canReadAudit) { + $result = @(Get-NTFSSecurityDescriptor -Path $orphanedFile | Get-NTFSOrphanedAudit -ErrorAction Stop) + + $result | Should -HaveCount 2 + $result | ForEach-Object -Process { $_.FullName | Should -Be $orphanedFile } + } + + It 'Should return an inherited entry, and nothing with -ExcludeInherited' -Skip:(-not $canReadAudit) { + $result = @(Get-NTFSOrphanedAudit -Path $inheritingFile -ErrorAction Stop) + $explicitResult = @(Get-NTFSOrphanedAudit -Path $inheritingFile -ExcludeInherited -ErrorAction Stop) + + $result | Should -HaveCount 1 + $result[0].Account.Sid | Should -Be 'S-1-5-21-1-2-3-1003' + $result[0].IsInherited | Should -BeTrue + $explicitResult | Should -BeNullOrEmpty } - $result = @(Get-NTFSOrphanedAudit -Path $orphanedFile) + It 'Should report the number of orphaned entries of each item in a verbose message' -Skip:(-not $canReadAudit) { + $messages = @(Get-NTFSOrphanedAudit -Path $orphanedFile -Verbose 4>&1 | Where-Object -FilterScript { + $_ -is [System.Management.Automation.VerboseRecord] }) + + $messages.Message | Should -Contain "Item $orphanedFile knows about 2 orphaned SIDs in its ACL" + } + } + + It 'Should write an error for a path that does not exist and continue with the next path' { + $result = @(Get-NTFSOrphanedAudit -Path $missing, $orphanedFile -ErrorVariable orphanedErrors -ErrorAction SilentlyContinue) + + $orphanedErrors | Should -HaveCount 1 + $orphanedErrors[0].FullyQualifiedErrorId | Should -BeLike 'ReadError,*' + $orphanedErrors[0].TargetObject | Should -Be $missing + $result | ForEach-Object -Process { $_.FullName | Should -Be $orphanedFile } + } + + It 'Should write an error for a security descriptor that was read without the audit entries' { + $sd = New-Object -TypeName 'Security2.FileSystemSecurity2' -ArgumentList ( + (Get-Item2 -Path $orphanedFile), [System.Security.AccessControl.AccessControlSections]::Access + ) - $result | Should -HaveCount 2 - $result | ForEach-Object -Process { $_ | Should -BeOfType [Security2.FileSystemAuditRule2] } + $result = @($sd | Get-NTFSOrphanedAudit -ErrorVariable orphanedErrors -ErrorAction SilentlyContinue) + + $result | Should -BeNullOrEmpty + $orphanedErrors | Should -HaveCount 1 + $orphanedErrors[0].FullyQualifiedErrorId | Should -BeLike 'ReadSecurityError,*' } - It 'Should return only the entries of -Account' -Skip:(-not $canReadAudit) { - $result = @(Get-NTFSOrphanedAudit -Path $orphanedFile -Account 'S-1-5-21-1-2-3-1002') + # The cmdlet page: without the privilege, the cmdlet reads no audit entries and reports none. + It 'Should return nothing and write no error without the Security privilege' -Skip:$canReadAudit { + $result = @(Get-NTFSOrphanedAudit -Path $orphanedFile -ErrorVariable orphanedErrors -ErrorAction SilentlyContinue) - $result | Should -HaveCount 1 + $orphanedErrors | Should -BeNullOrEmpty + $result | Should -BeNullOrEmpty } }