Defect 19, and the same gap in Remove-NTFSAudit. After the ReadFileError
for a path that doesn't exist, both cmdlets went on with a null item: the
removal failed with a NullReferenceException that they reported as a
second, misleading RemoveAceError, and with -PassThru the null item
stopped the command. Both now continue with the next path.
Tests: Access.Tests.ps1 and Audit.Tests.ps1, 2 tests each.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 17. Both cmdlets carried a removeSpecific field that no parameter
set, so they always took the rights away from matching entries; the
version history documents a -RemoveSpecific switch since 4.1. Both
cmdlets now have the switch, which removes only an entry that matches
exactly. The Security2 list overloads didn't pass the flag on, and the
audit item overload didn't support it; all overloads now do.
The applies-to field of both cmdlets is initialized; -AppliesTo is
mandatory in the Simple sets since defect 14, so it is always set when
used.
Tests: Access.Tests.ps1 3 tests, Audit.Tests.ps1 2 tests, on in-memory
security descriptors.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 16. Get-NTFSOrphanedAccess, Get-NTFSOrphanedAudit, and
Get-NTFSSimpleAccess inherit -Account and -SecurityDescriptor from
Get-NTFSAccess or Get-NTFSAudit but override ProcessRecord without them:
- All three now filter by -Account and process security descriptors
(Get-NTFSOrphanedAudit writes an error for one read without its SACL,
like Get-NTFSAudit).
- Get-NTFSOrphanedAudit wrote the entries of each item as one collection;
it now writes one object per entry.
- Get-NTFSOrphanedAccess kept the entries of the previous item and wrote
them in a finally block, like Get-NTFSAccess before; each item now
starts empty.
- SimpleFileSystemAccessRule had no view; it gets a table with Account,
Access Rights, and Type, grouped by folder, with the grouping control
that existed for it but was unused.
Tests: Access.Tests.ps1 6 tests; Audit.Tests.ps1 2 tests, CI-only because
they add audit entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Security review of this branch, Major findings:
- M4: Get-NTFSAudit took ownership of an item whose SACL it couldn't
read. Ownership grants no access to the SACL, so the retry always
failed, and it left the owner changed. The cmdlet now writes a
ReadSecurityError with the category PermissionDenied, as Get-NTFSOwner
does since defect 9; the page says so.
- M1: Remove-TestSandbox reset the ACLs recursively before it removed the
links. Measured: icacls /reset /T did not follow the junction (the
target's explicit entry stayed), but the links now go first anyway; a
folder that denies listing gets a reset without /T. New test: the ACL
of a junction target stays unchanged.
- m4: Assert-TestSandboxPath now rejects a path below a link, which can
point outside the sandbox (new test, failed before).
- M5: the Inherits column reads one ACL per displayed item; the
Get-ChildItem2 page names the cost and how to avoid it.
- M2: the comment of the CI-only Get-NTFSAudit repeat test states what it
guards; Access.Tests.ps1 guards the same loop fix without elevation.
- M3, the stale hash of Get-FileHash2, is fixed on ai/defects-c.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 7. FileSystemAuditRule2.GetFileSystemAuditRules set the
InheritanceEnabled property of every audit entry from
AreAccessRulesProtected, the protection of the DACL. It now uses
AreAuditRulesProtected, so the property, and the "Inheritance enabled"
header of the audit view, describe the audit entries.
Tests/Audit.Tests.ps1: 1 test on an in-memory security descriptor whose
SACL is protected and whose DACL is not.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 6. With -PassThru, Add-NTFSAudit returned the access entries of a
security descriptor in its SecurityDescriptor sets, and Remove-NTFSAudit
returned the access entries of the item in its Path sets. Both now return
the audit entries, as in their other parameter sets.
Tests/Audit.Tests.ps1: 2 tests; the Remove-NTFSAudit test writes a SACL
and runs in CI.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 5 (#4). -Account and -AccessRights of Add-NTFSAudit were both
declared at position 2, so a positional call failed with "Cannot bind
positional parameters because no names were given". -AccessRights is now
at position 3 in all four parameter sets, like in Remove-NTFSAudit.
The page's parameter metadata says position 3 as well. platyPS takes the
position from Get-Help, that is from the shipped help file, so
Update-MarkdownHelp kept the old value; the page, the regenerated help
file, and the build now agree.
Tests/Audit.Tests.ps1: 5 tests (positions in each parameter set and a
positional call against an in-memory security descriptor).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
- New-TestSandboxItem creates a uniquely named file or folder in a sandbox
after the path guard, replacing per-file copies.
- Block-TestReadPermission denies OWNER RIGHTS the right to read the
security descriptor of a sandbox item, so that reading it fails without
elevation.
- Remove-TestSandbox no longer stops when icacls cannot reset such an
item: Windows PowerShell turned the icacls message on stderr into a
terminating error; the item is still deleted through its folder.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 4, both parts:
- Get-NTFSAudit kept the entries of the previous item and wrote them in a
finally block, so a path whose security descriptor failed to read
returned the previous item's entries again. Each item now starts empty,
and entries are written only after a successful read.
- Without the Security privilege, the cmdlet read the descriptor without
its SACL and returned nothing, like an item without audit entries. It
now reads the SACL alone, so a missing privilege is a ReadSecurityError
("A required privilege is not held by the client"). A descriptor from
Get-NTFSSecurityDescriptor that was read without the SACL gets the same
error; FileSystemSecurity2 now records which sections it read
(internal, visible to NTFSSecurity).
Tests/Audit.Tests.ps1 (new): 3 tests. The repeat test needs the Security
privilege to add an audit entry and runs in CI.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>