- Set-NTFSSecurityDescriptor -Verbose names the sections that it writes,
or says that it writes nothing for an unchanged descriptor; its page
says "since it was read or last written" (review F-02).
- The pages of Enable-NTFSAccessInheritance, Disable-NTFSAccessInheritance,
and Set-NTFSInheritance get the #34 note, like the other fixed cmdlets
(review F-06).
- Set-TestOwner throws its own error when icacls fails, also when the
caller uses -ErrorAction Stop in Windows PowerShell (review F-07).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
- Set the prerelease label rc3, and add 5.0.0-rc2 to the versions that
the PowerShell Gallery already has.
- Extend the description of the manifest, which the PowerShell Gallery
shows, with the archive note (maintainer decision of 2026-10-06,
Decision 18).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Written through its UNC path, the DACL of a share root can't re-inherit
from the parent folder on the server: Windows drops the inherited entries
of a DACL in the auto-inherit format and stores the others as explicit
copies. icacls and Set-Acl behave the same; a subfolder through the share
and the local path keep them (#67).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The access and audit cmdlets wrote the owner of an item back with the
entries they changed. For a DACL without the auto-inherit flag, Windows
returns the owner and the group even when only the DACL is read, and the
cmdlets wrote every section that the descriptor held. Without the Restore
privilege, or on a file server that refuses the owner, the write failed
with error 1307 (#34).
- Add-NTFSAccess, Clear-NTFSAccess, Add-NTFSAudit, and Clear-NTFSAudit
read only the DACL or the SACL. FileSystemSecurity2.Write(),
Remove-NTFSAccess, and Remove-NTFSAudit write only the sections they
read, which also fixes the access inheritance cmdlets.
- Read together with the SACL, the inherited entries of such a DACL lose
their inherited flag when the parent folder has no SACL, and the
cmdlets stored them as explicit copies. Get-NTFSSecurityDescriptor now
reads the DACL in a separate call.
- Set-NTFSSecurityDescriptor writes only the sections that changed since
they were read; an unchanged descriptor writes nothing (maintainer
decision of 2026-10-06).
- Clear-NTFSAudit writes nothing for an item without a SACL, and reports
an error without the Security privilege (maintainer decision).
The regression tests failed before and pass after the fix in Windows
PowerShell 5.1 and PowerShell 7, elevated and as a basic user.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The maintainer decided on 2026-10-06 to publish 5.0.0-rc3 before 5.0.0
and to archive NTFSSecurity in favor of WindowsAccessControl.
- Decision 18: the project will be archived; the notes in the README,
the docs home, and the changelog stay until then.
- activeContext: rc3 is the focus. #34 reproduces locally with rc2, on a
file owned by TrustedInstaller without the Restore privilege, so CI can
test the fix without a file server.
- progress: rc3, then 5.0.0, with the version steps of each.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
NTFSSecurity will be archived soon. The README, the documentation home,
which is also the wiki home, and the changelog now point users to
WindowsAccessControl, which is on the PowerShell Gallery. The changelog
entry also reaches the release notes of the next prerelease.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The maintainer approved a label scheme on 2026-10-06, and it was applied
to the 42 issues triaged on 2026-10-05, with the new label Needs Info for
issues that wait for their reporters.
- Decision 17: the meaning of each label and the close reasons.
- activeContext and progress: the labels are applied; five issues wait
for their reporters.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
5.0.0-rc2 is on the PowerShell Gallery and in the GitHub releases. The
PRs #99 to #106 were merged in order with merge commits, CI on master
passed, and the tag 5.0.0-rc2 on 7ddda8d published it on the third
attempt of the release run, after GitHub's Actions outage of 2026-10-05.
The open issues got their replies, 16 were closed, and the follow-up
issues #107 to #111 track the open Minor review findings.
- Decision 14: repository hardening is optional; the outdated "pending"
text is gone.
- Decision 15: merge stacked pull requests in order with merge commits.
- Decision 16: fix only reproducible bugs (the maintainer's decision D6).
- activeContext and progress: the CI fix 629f4e7, the copied inherited
entries behind #34, the issue state, and the next step (test rc2, then
5.0.0 or rc3).
- techContext: the current versions, the second workstation, and
one-line commands for the maintainer.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Enable-NTFSAuditInheritance, Disable-NTFSAuditInheritance, and
Set-NTFSInheritance -AuditInheritanceEnabled failed with "(5) Access is
denied" for a file or folder without a SACL, also elevated with the
Security privilege. The cmdlets read only the audit section and changed
the flag that disables or enables audit inheritance. AlphaFS writes that
flag only together with a SACL, so it wrote no section at all, which
Windows denies; the retry as owner repeated the same write. An empty SACL
is now added first, but only to a descriptor that was read with its SACL.
The elevated CI runs of #100 to #106 showed this through the test of an
omitted -AccessInheritanceEnabled. From #104 on, the test that keeps the
inherited entries of a security descriptor failed as well: elevated,
Get-NTFSSecurityDescriptor reads the SACL, and Windows then returns a DACL
that isn't in the auto-inherit format, such as that of a file in the temp
folder of the user, without its inherited flags. The test now reads the
access section only and checks that the descriptor has inherited entries.
Tests: five cases for items without audit entries, red with "Access is
denied" before the fix; the test that keeps the explicit audit entries now
checks the errors and the inheritance state of both calls; a test checks
that a descriptor read without its audit entries gets no SACL, which would
replace the audit entries of the item when it is written.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Keep the details of the pending repository settings out of the Memory
Bank, which is public. Replace the test for the one published version with a
list of the versions that the PowerShell Gallery has, which the release guide
now asks to maintain, and name the description test after its assertion.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Remove the fixed defects from progress.md, rewrite activeContext.md for the
maintainer, and curate systemPatterns.md below its line budget.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Set the prerelease label rc2, describe the module as a PowerShell module in
the manifest, which the PowerShell Gallery shows, and keep the README free
of a prerelease version, which outlives the release. Tests check the
description, that the published 5.0.0-rc1 isn't reused, and the README.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
An empty Get-ChildItem2 -Attributes value, such as 0 or None in
PowerShell 7, matched every item and returned hidden items as well; it now
stops the cmdlet with AttributesEmpty, as Get-ChildItem rejects it. The page
says that the + and ! operators of Get-ChildItem aren't supported and that
-Recurse still enters hidden folders, and the changelog says that a call
with several attributes now returns more items. The type data test starts
Windows PowerShell, where the import failed, from both CI legs and checks
that LengthOnDisk is still there.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The types file added the alias Size of LengthOnDisk to System.IO.FileInfo.
Type data can't replace an existing member, so in Windows PowerShell the
import failed when another module had added a Size member first (#82).
BREAKING CHANGE: use LengthOnDisk instead of Size.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-ChildItem2 -Attributes returned only the items that had all the listed
attributes, so -Attributes Hidden, ReadOnly returned nothing where
Get-ChildItem returns both kinds of items. It now returns the items that have
any of them (#5).
BREAKING CHANGE: to get only the items with all the listed attributes,
filter the result with Where-Object, as the cmdlet page shows.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The fix for #17 stopped adding Synchronize to an Allow rule with generic
rights, which bypassed the exact match of FileSystemSecurity.RemoveAccessRule:
-AccessRights GenericAll left a Synchronize-only entry behind when the entry
also had Synchronize. RemoveRule now does what FileSystemSecurity does,
without its validation: it removes a rule that matches an entry exactly as it
is, and otherwise without Synchronize. It covers every mask that .NET
rejects, not only the generic rights. The tests cover -RemoveSpecific, a
Deny entry, a partial generic mask, and that nothing else is removed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
FileSystemSecurity.RemoveAccessRule rebuilds a rule that doesn't match an
entry exactly and rejects generic rights then, so removing an entry with
GENERIC_ALL failed with "The value '269484032' is not valid". Windows keeps
generic rights in the inherit-only entries of folders. Such a rule is now
removed through ModifyAccessRule, without the added Synchronize right
(#17).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Nine cmdlets still read the PWD variable for the default location when
-Path was omitted, so #86 remained for that form; they now use
GetCurrentLocation. Copy-Item2 writes the object that CopyTo returns for the
copy instead of relying on AlphaFS to update the source object, and a test
covers a folder.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Mark the Set-NTFSInheritance change as breaking and warn that scripts that
used it to drop the inherited access entries now leave broader access in
place. Report any failure to create the hash algorithm as
HashAlgorithmNotAvailable, assert that error ID, check that the
MACTripleDES warning appears once, and guard the descriptor test.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The new FAQ page answers the questions that the issues ask again and again
and links the pages with the details. The Get-NTFSEffectiveAccess page said
that a security descriptor produces no result, and the Copy-Item2 page now
says that -PassThru returns the copy; tests pin both -PassThru objects.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Windows PowerShell binds an object that is passed by position to a string
parameter through ToString, which returns only the name of a child item, so
the cmdlets looked for it in the current location. The path parameters now
convert file and folder objects to their full path (#88).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
A variable named PWD in the scope of the caller, such as a loop variable,
hid the automatic variable, and every cmdlet failed with a
NullReferenceException, also for an absolute path. The cmdlets now read
the current file system location from the session state, and only for a
relative path (#86).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The message overloads of BaseCmdletWithPrivControl hide the methods of
Cmdlet, so every message went through string.Format, also one without
arguments. A path with braces in it, such as C:\Data\{Archive}, then
stopped the cmdlet with a FormatException (#3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The behavior stays: the cmdlet removes the explicit entries and disables
inheritance without copying the inherited ones. The parameter text now
states the empty DACL and its risk, and a test pins the behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
-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>
Disable-NTFSAuditInheritance -RemoveInheritedAccessRules is now
-RemoveInheritedAuditRules, and Enable-NTFSAuditInheritance
-RemoveExplicitAccessRules is now -RemoveExplicitAuditRules. The old names
remain aliases, so existing scripts keep working.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-FileHash2 failed in PowerShell 7 for every algorithm, because the hash
method referenced RIPEMD160, which .NET Core and later lack. RIPEMD160 and
MACTripleDES are now created by name; requesting one where .NET lacks it
stops the cmdlet with an error that names the algorithm and points to
Windows PowerShell 5.1. MACTripleDES uses a random key, so its result
differs on every call; the value is deprecated, and the cmdlet warns when
it is used.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Copy-Item2, Move-Item2, and Remove-Item2 wrote the item with -PassThru
also when -WhatIf or a declined confirmation skipped the operation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The privilege cmdlets declared a public Path property that was never a
parameter, and Remove-Item2 declared a filter field that nothing read.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Copy-Item2 and Move-Item2 named the source path as the destination,
Disable-Privileges said that the privileges were now enabled, and the
warning of Get-NTFSEffectiveAccess misspelled the privilege.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 22:
- [OutputType]: Test-Path2 writes System.Boolean, not file objects;
Get-FileHash2 writes the file object with Hash and Algorithm, not access
rules; Add-NTFSAudit and Remove-NTFSAudit write audit entries since
defect 6; Copy-Item2, Move-Item2, Remove-Item2, and the five inheritance
cmdlets with -PassThru declared no type.
- Enable-Privileges and Disable-Privileges with -PassThru wrote the
privileges as one collection; they now enumerate it.
- New-NTFSSymbolicLink -PassThru returned a FileInfo for a link to a
folder; it now returns a DirectoryInfo.
The OUTPUTS sections of the pages name the same types.
Tests/OutputTypes.Tests.ps1 (new): 15 tests; Disable-Privileges and the
symbolic link need privileges and run in CI.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The cmdlets that take ownership of an item to repeat a denied operation
left the account that ran them as the owner when the second attempt failed
as well. BaseCmdlet.InvokeAsOwner now restores the previous owner on every
exit path and reports a failed restore as RestoreOwnerError.
Add-NTFSAccess, Add-NTFSAudit, Remove-NTFSAccess, and Remove-NTFSAudit
wrote the unchanged entries of an item with -PassThru after a failed
change; they now continue with the next path.
The inheritance tests assert the error identity and cover a missing path
on every runner.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
- activeContext.md: the results of ai/defects-c and the next step.
- progress.md: group C is fixed on ai/defects-c (not merged yet).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Found while fixing defect 3, in the same loop: the hash variable lived
outside the loop, and after a GetHashError the cmdlet still wrote a
result for the file, with the hash of the previous file. Each path now
starts without a hash, and a failed read writes only the error.
Tests/FileHash.Tests.ps1: 1 test with a file opened without sharing;
like the other Get-FileHash2 tests, it skips in PowerShell 7 until the
RIPEMD160 reference goes (decision D5).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 21. For a -Target that didn't exist, New-NTFSHardLink failed with
"The target path exist, cannot create the link", the opposite of the
cause. The message now names the target and says that it does not exist.
Tests/Links.Tests.ps1 (new): 2 tests, one of them for a link that is
created.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 20 (#74). Enable-NTFSAccessInheritance,
Disable-NTFSAccessInheritance, Enable-NTFSAuditInheritance,
Disable-NTFSAuditInheritance, and Set-NTFSInheritance wrote the
-PassThru object in a finally block. After a failed change, such as an
audit change without the Security privilege, they returned the unchanged
state, which made the inheritance look disabled; when the item could not
be read at all, reading the state in the finally block threw and stopped
the command. The object is now written only after a successful change.
Tests/Inheritance.Tests.ps1: 5 tests. The audit tests need the missing
privilege and skip in CI; the read-deny tests skip where the Backup
privilege may bypass the deny entry (CI).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
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 18. Copy-Item2, Move-Item2, and Remove-Item2 left ProcessRecord
with "return" when a path didn't exist and, for copy and move, when the
destination file existed without -Force, so the remaining paths of the
same -Path array were not processed. They now write the error and
continue with the next path.
Tests/ItemCmdlets.Tests.ps1: 5 tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Write orphaned audit entries outside the read error handler, so that a
stopped pipeline isn't reported as a read error. Pass -RemoveSpecific
through the string path overload of RemoveFileSystemAuditRule, and state
on the Get-NTFSSimpleAccess page that the security descriptor of a file
is reported.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>