You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

587 lines
37 KiB

Ai/docs alignment (#91) * chore: initialize the memory bank Add the canonical .memory-bank base with evidence-based project context: purpose and scope, workflows, stack and validation commands, architecture map, decisions, and the open work found while documenting the cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * docs: align documentation with the cmdlet source - Fill all 36 platyPS cmdlet pages from the C# source: synopsis, description, parameters, defaults, examples, inputs, outputs, and notes, including documented limitations of the current code - Check every example against live parameter metadata and run them in a sandbox; fix examples that did not work (CSV restore, account filter, recursive inheritance, -AccessRights typos) - Rewrite the home, concepts, examples, README, and contributor pages; add a grouped cmdlet overview, module settings, privileges, long paths, and the platyPS workflow - Document Remove-Item2 -PassThru as renamed after 4.2.6 (#64) - Fix mkdocs.yml navigation, edit_uri, and copyright markup; add build.os and a pinned MkDocs version for Read the Docs - Point online help links to the pages on GitHub; add CHANGELOG.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: build the module and check the docs against the build The documentation check ran Update-MarkdownHelp against the NTFSSecurity release from the PowerShell Gallery (4.2.6), so it failed for every unreleased parameter change. PR #91 failed because 4.2.6 still has Remove-Item2 -PassThur while the source and the docs have -PassThru. - Build NTFSSecurity.csproj in Release on the Visual Studio 2022 image, using the .NET Framework 4.5.2 reference assemblies package instead of an installed targeting pack - Check Docs/Cmdlets against the module built from source - Pin platyPS 0.14.2 and MarkdownLinkCheck 0.2.0, and enable TLS 1.2 so the NuGet provider bootstrap works Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * chore: record the green PR 91 build in the memory bank Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
# Changelog
All notable changes to this project are documented in this file.
The format is based on
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Releases up to
4.2.6 are described in the [version history](Docs/Version-History.md).
Ai/docs alignment (#91) * chore: initialize the memory bank Add the canonical .memory-bank base with evidence-based project context: purpose and scope, workflows, stack and validation commands, architecture map, decisions, and the open work found while documenting the cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * docs: align documentation with the cmdlet source - Fill all 36 platyPS cmdlet pages from the C# source: synopsis, description, parameters, defaults, examples, inputs, outputs, and notes, including documented limitations of the current code - Check every example against live parameter metadata and run them in a sandbox; fix examples that did not work (CSV restore, account filter, recursive inheritance, -AccessRights typos) - Rewrite the home, concepts, examples, README, and contributor pages; add a grouped cmdlet overview, module settings, privileges, long paths, and the platyPS workflow - Document Remove-Item2 -PassThru as renamed after 4.2.6 (#64) - Fix mkdocs.yml navigation, edit_uri, and copyright markup; add build.os and a pinned MkDocs version for Read the Docs - Point online help links to the pages on GitHub; add CHANGELOG.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: build the module and check the docs against the build The documentation check ran Update-MarkdownHelp against the NTFSSecurity release from the PowerShell Gallery (4.2.6), so it failed for every unreleased parameter change. PR #91 failed because 4.2.6 still has Remove-Item2 -PassThur while the source and the docs have -PassThru. - Build NTFSSecurity.csproj in Release on the Visual Studio 2022 image, using the .NET Framework 4.5.2 reference assemblies package instead of an installed targeting pack - Check Docs/Cmdlets against the module built from source - Pin platyPS 0.14.2 and MarkdownLinkCheck 0.2.0, and enable TLS 1.2 so the NuGet provider bootstrap works Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * chore: record the green PR 91 build in the memory bank Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
## [Unreleased]
### Added
- Publish the documentation in the
[wiki](https://github.com/raandree/NTFSSecurity/wiki), generated from the
`Docs` folder after every change, with a sidebar that lists all cmdlets
ci: publish releases from CI on a version tag, starting with 5.0.0-rc1 Pushing a tag such as 5.0.0 or 5.0.0-rc1 on master now publishes the package that the build job built and tested to the PowerShell Gallery and creates the GitHub release with NTFSSecurity.zip. - New-ModulePackage.ps1 copies only the FileList files of the Release build, so no debug symbols, XML documentation, or copy of System.Management.Automation.dll ship. It builds the nupkg with Compress-PSResource and adds the command tags (PSIncludes_Cmdlet, PSCmdlet_*, PSCommand_*) that PSResourceGet leaves out and that the Gallery uses to list cmdlets and that Find-Command searches. Every CI run builds and uploads the packages. - Get-ReleaseInfo.ps1 returns the version and release notes: a dated CHANGELOG section for a release, the [Unreleased] section for a prerelease. - The release job checks that the tag matches the manifest version and points to a commit on master, reads the API key from the environment powershell-gallery, and skips steps already done, so a rerun is safe. - The manifest gets the prerelease label rc1 and a release notes link; the 5.0.0 changelog entries move back to [Unreleased] until the final release. - Tests/Release.Tests.ps1 covers both scripts and the packages; the changelog check moves there from Manifest.Tests.ps1. - Docs/Contributing/05-Releasing.md describes the one-time setup and the release steps; Docs/README.md explains -AllowPrerelease. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
- Link the release notes in the PowerShell Gallery to this changelog
Ai/docs alignment (#91) * chore: initialize the memory bank Add the canonical .memory-bank base with evidence-based project context: purpose and scope, workflows, stack and validation commands, architecture map, decisions, and the open work found while documenting the cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * docs: align documentation with the cmdlet source - Fill all 36 platyPS cmdlet pages from the C# source: synopsis, description, parameters, defaults, examples, inputs, outputs, and notes, including documented limitations of the current code - Check every example against live parameter metadata and run them in a sandbox; fix examples that did not work (CSV restore, account filter, recursive inheritance, -AccessRights typos) - Rewrite the home, concepts, examples, README, and contributor pages; add a grouped cmdlet overview, module settings, privileges, long paths, and the platyPS workflow - Document Remove-Item2 -PassThru as renamed after 4.2.6 (#64) - Fix mkdocs.yml navigation, edit_uri, and copyright markup; add build.os and a pinned MkDocs version for Read the Docs - Point online help links to the pages on GitHub; add CHANGELOG.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: build the module and check the docs against the build The documentation check ran Update-MarkdownHelp against the NTFSSecurity release from the PowerShell Gallery (4.2.6), so it failed for every unreleased parameter change. PR #91 failed because 4.2.6 still has Remove-Item2 -PassThur while the source and the docs have -PassThru. - Build NTFSSecurity.csproj in Release on the Visual Studio 2022 image, using the .NET Framework 4.5.2 reference assemblies package instead of an installed targeting pack - Check Docs/Cmdlets against the module built from source - Pin platyPS 0.14.2 and MarkdownLinkCheck 0.2.0, and enable TLS 1.2 so the NuGet provider bootstrap works Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * chore: record the green PR 91 build in the memory bank Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
### Changed
- **Breaking:** require Windows PowerShell 5.1 or PowerShell 7, and declare
support for both editions in the module manifest
([#61](https://github.com/raandree/NTFSSecurity/issues/61)); the manifest
declared PowerShell 2.0 and .NET Framework 3.5, although the module needs
.NET Framework 4.5.2
- Rename the `-PassThur` parameter of `Remove-Item2` to `-PassThru`;
`-PassThur` still works as an alias
([#64](https://github.com/raandree/NTFSSecurity/pull/64))
ci: publish releases from CI on a version tag, starting with 5.0.0-rc1 Pushing a tag such as 5.0.0 or 5.0.0-rc1 on master now publishes the package that the build job built and tested to the PowerShell Gallery and creates the GitHub release with NTFSSecurity.zip. - New-ModulePackage.ps1 copies only the FileList files of the Release build, so no debug symbols, XML documentation, or copy of System.Management.Automation.dll ship. It builds the nupkg with Compress-PSResource and adds the command tags (PSIncludes_Cmdlet, PSCmdlet_*, PSCommand_*) that PSResourceGet leaves out and that the Gallery uses to list cmdlets and that Find-Command searches. Every CI run builds and uploads the packages. - Get-ReleaseInfo.ps1 returns the version and release notes: a dated CHANGELOG section for a release, the [Unreleased] section for a prerelease. - The release job checks that the tag matches the manifest version and points to a commit on master, reads the API key from the environment powershell-gallery, and skips steps already done, so a rerun is safe. - The manifest gets the prerelease label rc1 and a release notes link; the 5.0.0 changelog entries move back to [Unreleased] until the final release. - Tests/Release.Tests.ps1 covers both scripts and the packages; the changelog check moves there from Manifest.Tests.ps1. - Docs/Contributing/05-Releasing.md describes the one-time setup and the release steps; Docs/README.md explains -AllowPrerelease. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
- Publish the module as a Release build that contains only the module
files; 4.2.6 was a Debug build with debug symbols and a copy of
`System.Management.Automation.dll`
Ai/docs alignment (#91) * chore: initialize the memory bank Add the canonical .memory-bank base with evidence-based project context: purpose and scope, workflows, stack and validation commands, architecture map, decisions, and the open work found while documenting the cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * docs: align documentation with the cmdlet source - Fill all 36 platyPS cmdlet pages from the C# source: synopsis, description, parameters, defaults, examples, inputs, outputs, and notes, including documented limitations of the current code - Check every example against live parameter metadata and run them in a sandbox; fix examples that did not work (CSV restore, account filter, recursive inheritance, -AccessRights typos) - Rewrite the home, concepts, examples, README, and contributor pages; add a grouped cmdlet overview, module settings, privileges, long paths, and the platyPS workflow - Document Remove-Item2 -PassThru as renamed after 4.2.6 (#64) - Fix mkdocs.yml navigation, edit_uri, and copyright markup; add build.os and a pinned MkDocs version for Read the Docs - Point online help links to the pages on GitHub; add CHANGELOG.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: build the module and check the docs against the build The documentation check ran Update-MarkdownHelp against the NTFSSecurity release from the PowerShell Gallery (4.2.6), so it failed for every unreleased parameter change. PR #91 failed because 4.2.6 still has Remove-Item2 -PassThur while the source and the docs have -PassThru. - Build NTFSSecurity.csproj in Release on the Visual Studio 2022 image, using the .NET Framework 4.5.2 reference assemblies package instead of an installed targeting pack - Check Docs/Cmdlets against the module built from source - Pin platyPS 0.14.2 and MarkdownLinkCheck 0.2.0, and enable TLS 1.2 so the NuGet provider bootstrap works Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * chore: record the green PR 91 build in the memory bank Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
- Document every cmdlet with synopsis, description, parameters, examples,
inputs, outputs, and notes, checked against the source code
- Rewrite the home, concepts, examples, and contributor pages to match the
current cmdlets, including module settings, privileges, and long paths
- Move the version history and the installation instructions from the wiki
ci: publish releases from CI on a version tag, starting with 5.0.0-rc1 Pushing a tag such as 5.0.0 or 5.0.0-rc1 on master now publishes the package that the build job built and tested to the PowerShell Gallery and creates the GitHub release with NTFSSecurity.zip. - New-ModulePackage.ps1 copies only the FileList files of the Release build, so no debug symbols, XML documentation, or copy of System.Management.Automation.dll ship. It builds the nupkg with Compress-PSResource and adds the command tags (PSIncludes_Cmdlet, PSCmdlet_*, PSCommand_*) that PSResourceGet leaves out and that the Gallery uses to list cmdlets and that Find-Command searches. Every CI run builds and uploads the packages. - Get-ReleaseInfo.ps1 returns the version and release notes: a dated CHANGELOG section for a release, the [Unreleased] section for a prerelease. - The release job checks that the tag matches the manifest version and points to a commit on master, reads the API key from the environment powershell-gallery, and skips steps already done, so a rerun is safe. - The manifest gets the prerelease label rc1 and a release notes link; the 5.0.0 changelog entries move back to [Unreleased] until the final release. - Tests/Release.Tests.ps1 covers both scripts and the packages; the changelog check moves there from Manifest.Tests.ps1. - Docs/Contributing/05-Releasing.md describes the one-time setup and the release steps; Docs/README.md explains -AllowPrerelease. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
into the documentation, and complete the version history with the release
dates from the PowerShell Gallery, the missing notes for 4.2.2, 4.2.5, and
4.2.6, and detailed notes for 4.2.4
- Describe the module as a PowerShell module in the manifest, which the
PowerShell Gallery shows; it said Windows PowerShell, although the module
supports PowerShell 7 as well
- Rename `-RemoveInheritedAccessRules` of `Disable-NTFSAuditInheritance` to
`-RemoveInheritedAuditRules` and `-RemoveExplicitAccessRules` of
`Enable-NTFSAuditInheritance` to `-RemoveExplicitAuditRules`, because they
act on audit entries; the old names still work as aliases
- **Breaking:** `Set-NTFSInheritance` keeps entries like the dedicated
cmdlets: `-AccessInheritanceEnabled $false` now copies the inherited access
entries into the DACL instead of removing them, and
`-AuditInheritanceEnabled $true` now keeps the explicit audit entries. A
script that used `-AccessInheritanceEnabled $false` to drop the inherited
access entries now leaves them in place, which grants broader access than
before. To remove the entries, use
`Disable-NTFSAccessInheritance -RemoveInheritedAccessRules` or
`Enable-NTFSAuditInheritance -RemoveExplicitAuditRules`
- **Breaking:** `Get-ChildItem2 -Attributes` returns the items that have any
of the listed attributes, like `Get-ChildItem`; it returned only the items
that had all of them. A call that lists several attributes now returns
more items, including hidden and system items when those are in the
list, so review calls whose result is deleted or whose permissions are
changed. To get the old result, filter with `Where-Object`, as the cmdlet
page shows. An empty value, such as `0`, is now an error; it returned
every item, also the hidden ones
([#5](https://github.com/raandree/NTFSSecurity/issues/5))
- **Breaking:** remove the alias `Size` of `LengthOnDisk` from the files of
`Get-ChildItem`, which made the import fail in Windows PowerShell when
another module had added a `Size` member; use `LengthOnDisk`
([#82](https://github.com/raandree/NTFSSecurity/issues/82))
fix: write only the sections of the security descriptor that a cmdlet changes 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>
4 weeks ago
- Write only the sections of a security descriptor that changed since it
was read in `Set-NTFSSecurityDescriptor`, such as the DACL after
`Add-NTFSAccess -SecurityDescriptor`; a descriptor without changes writes
nothing, and `-Verbose` names the sections that the cmdlet writes. The
cmdlet wrote every section that `Get-NTFSSecurityDescriptor` had read,
also an unchanged owner, which failed with error 1307 where the account
may not assign that owner
fix: write only the sections of the security descriptor that a cmdlet changes 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>
4 weeks ago
([#34](https://github.com/raandree/NTFSSecurity/issues/34))
- Document that `Get-NTFSEffectiveAccess -ServerName` works only for the
administrators of the named computer and the members of its group Access
Control Assistance Operators; any other account gets the error "Access is
denied" and no result
- **Breaking:** require `-Path` and `-Target` in `New-NTFSHardLink` and
`New-NTFSSymbolicLink`. Without `-Path`, they failed with an index error;
without `-Target`, they used the current location, so
`New-NTFSSymbolicLink -Path Link` created a link to the current folder
- **Breaking:** write a non-terminating error in `New-NTFSHardLink` and
`New-NTFSSymbolicLink` for a link that they can't create, such as for an
existing `-Path`, a missing `-Target`, or a path with a character that
Windows doesn't allow, and continue with the next link; they stopped
with a terminating error. A script that relies on the stop needs
`-ErrorAction Stop`
- Name the computer in the warning of `Get-NTFSEffectiveAccess` when the
computer of `-ServerName` can't be reached
- Document that `Get-NTFSHardLink` and `New-NTFSHardLink -PassThru` fail for
a path whose root isn't the root of the volume that holds the file, such
as a path on a drive made with `subst`. `Get-NTFSHardLink` writes a
`FileNotFound` error for a file that exists, and
`New-NTFSHardLink -PassThru` creates the link and then stops with a
`FileNotFoundException`. A volume that is mounted into a folder, and a
junction or symbolic link to another volume, probably fail the same way.
Use a path that starts at the root of the volume
- **Breaking:** match `Get-ChildItem2 -Filter` once, in the cmdlet, with the
wildcard rules that `Get-ChildItem -Filter` applies in Windows PowerShell
5.1, in both editions, and on the real name of an item, not its 8.3 short
name. `Report.*` also returns `Report`, which has no dot; a pattern that
ends in a dot, such as `Report.` or `*.`, returns the names without a dot;
`*.*.*` returns every item; and a question mark also matches nothing at
the end of a name and before a dot, so `a?` also returns `a`. An empty
`-Filter` returns every item, like `*`, instead of nothing, and a pattern
of more than 32,767 characters is a parameter error. Two kinds of pattern
are not like Windows PowerShell 5.1: blanks at the end of a pattern, also
before a final dot, are part of it, where Windows PowerShell 5.1 drops them,
and a pattern that ends in an even number of dots, such as two, is
accepted, where Windows PowerShell 5.1 stops with an error. In
PowerShell 7, `Get-ChildItem2` deliberately differs from
`Get-ChildItem -Filter` for some patterns, for example for a pattern that
ends in a dot, unless an asterisk comes right before the dot (the pattern
of a single dot returns every item), and for a pattern in which an asterisk
is followed by a dot and question marks
- **Breaking:** write a non-terminating error in `Get-NTFSOrphanedAccess` for
an item that it can't read for a reason other than a denied access, and
continue with the next item: `ReadSecurityError` with the category
`OpenError`; it wrote a warning. A script that reads the failure with
`-WarningVariable` needs `-ErrorVariable`, and `-ErrorAction Stop` now
stops at it
- Take `-SecurityDescriptor` of `Set-NTFSSecurityDescriptor` at position 1,
like the first positional parameter of the other cmdlets; it was at
position 2. A positional call isn't affected, because it is the only
positional parameter
- Document that `Get-NTFSEffectiveAccess` writes the error "Access is denied"
for a user account of the domain when the user who runs the cmdlet has no
domain credentials, such as a local standard user
Ai/docs alignment (#91) * chore: initialize the memory bank Add the canonical .memory-bank base with evidence-based project context: purpose and scope, workflows, stack and validation commands, architecture map, decisions, and the open work found while documenting the cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * docs: align documentation with the cmdlet source - Fill all 36 platyPS cmdlet pages from the C# source: synopsis, description, parameters, defaults, examples, inputs, outputs, and notes, including documented limitations of the current code - Check every example against live parameter metadata and run them in a sandbox; fix examples that did not work (CSV restore, account filter, recursive inheritance, -AccessRights typos) - Rewrite the home, concepts, examples, README, and contributor pages; add a grouped cmdlet overview, module settings, privileges, long paths, and the platyPS workflow - Document Remove-Item2 -PassThru as renamed after 4.2.6 (#64) - Fix mkdocs.yml navigation, edit_uri, and copyright markup; add build.os and a pinned MkDocs version for Read the Docs - Point online help links to the pages on GitHub; add CHANGELOG.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: build the module and check the docs against the build The documentation check ran Update-MarkdownHelp against the NTFSSecurity release from the PowerShell Gallery (4.2.6), so it failed for every unreleased parameter change. PR #91 failed because 4.2.6 still has Remove-Item2 -PassThur while the source and the docs have -PassThru. - Build NTFSSecurity.csproj in Release on the Visual Studio 2022 image, using the .NET Framework 4.5.2 reference assemblies package instead of an installed targeting pack - Check Docs/Cmdlets against the module built from source - Pin platyPS 0.14.2 and MarkdownLinkCheck 0.2.0, and enable TLS 1.2 so the NuGet provider bootstrap works Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * chore: record the green PR 91 build in the memory bank Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
### Deprecated
- Deprecate NTFSSecurity as a whole: the project will be archived soon.
Move to
[WindowsAccessControl](https://github.com/raandree/WindowsAccessControl),
fix: write only the sections of the security descriptor that a cmdlet changes 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>
4 weeks ago
which is also on the PowerShell Gallery. The description of NTFSSecurity
in the PowerShell Gallery says so as well
- Deprecate the `-PassThur` alias of `Remove-Item2`; use `-PassThru`
- Deprecate the `MACTripleDES` value of `Get-FileHash2 -Algorithm`: it uses
a random key, so its result differs on every call; the cmdlet now warns
when you use it
Ai/docs alignment (#91) * chore: initialize the memory bank Add the canonical .memory-bank base with evidence-based project context: purpose and scope, workflows, stack and validation commands, architecture map, decisions, and the open work found while documenting the cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * docs: align documentation with the cmdlet source - Fill all 36 platyPS cmdlet pages from the C# source: synopsis, description, parameters, defaults, examples, inputs, outputs, and notes, including documented limitations of the current code - Check every example against live parameter metadata and run them in a sandbox; fix examples that did not work (CSV restore, account filter, recursive inheritance, -AccessRights typos) - Rewrite the home, concepts, examples, README, and contributor pages; add a grouped cmdlet overview, module settings, privileges, long paths, and the platyPS workflow - Document Remove-Item2 -PassThru as renamed after 4.2.6 (#64) - Fix mkdocs.yml navigation, edit_uri, and copyright markup; add build.os and a pinned MkDocs version for Read the Docs - Point online help links to the pages on GitHub; add CHANGELOG.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: build the module and check the docs against the build The documentation check ran Update-MarkdownHelp against the NTFSSecurity release from the PowerShell Gallery (4.2.6), so it failed for every unreleased parameter change. PR #91 failed because 4.2.6 still has Remove-Item2 -PassThur while the source and the docs have -PassThru. - Build NTFSSecurity.csproj in Release on the Visual Studio 2022 image, using the .NET Framework 4.5.2 reference assemblies package instead of an installed targeting pack - Check Docs/Cmdlets against the module built from source - Pin platyPS 0.14.2 and MarkdownLinkCheck 0.2.0, and enable TLS 1.2 so the NuGet provider bootstrap works Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * chore: record the green PR 91 build in the memory bank Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
### Fixed
- Retain the supplied path in the public access- and audit-rule constructors
so their `FullName`, `Name`, and simplified audit conversions identify
the item
- Reduce `ReadData` to `Read` in simplified audit entries, and compare them
with audit entries rather than access entries, preserving equality with
themselves and with equivalent simplified audit objects
- Compare boxed privilege output values by their privilege and attributes;
the object overload rejected privilege values and recursively compared
an attributes enum instead
- Convert a `FileSecurity` or a `DirectorySecurity` object to
`FileSystemSecurity2` in the .NET API of `Security2.dll`: the conversions
ignored the descriptor and threw an exception for an empty path. The result
wraps the descriptor and has no item: `FullName` and `Name` are `$null`,
`Write()` throws an `InvalidOperationException`, and the entries, the
owner, the inheritance, and the effective access can be read; an inherited
entry has no source. PowerShell uses the conversion to bind
`-SecurityDescriptor`, so the cmdlets now accept the object that `Get-Acl`
returns, where they stopped with a parameter binding error. Such a
descriptor can't be written, so `Set-NTFSSecurityDescriptor` writes a
`WriteSdError` for it, and the audit cmdlets write a `ReadSecurityError`
for one that has no audit entries
- **Breaking:** fix `RemoveFileSystemAccessRuleAll` and
`RemoveFileSystemAuditRuleAll` of the .NET API, which ignored the list of
accounts and removed every explicit entry; they remove only the entries of
the listed accounts, and an empty list removes none
- **Breaking:** fix the overloads of `AddFileSystemAccessRule` and
`AddFileSystemAuditRule` of the .NET API that take a path and a list of
accounts, which did nothing until the caller enumerated the result; they
write at once, and an exception reaches the caller of the method
- Fix a module setting `EnablePrivileges` that is missing or not `$true` or
`$false`, for example after
`(Get-Module NTFSSecurity).PrivateData['EnablePrivileges'] = 'false'`: the
cmdlets that use privileges failed with an `InvalidCastException` or a
`NullReferenceException`; they stop with one error,
`EnablePrivilegesSettingInvalid`, which names the setting
- Fix `Clear-NTFSAccess -DisableInheritance` and `Set-NTFSSecurityDescriptor`,
which reported a `RestoreOwnerError` for an owner that had not changed:
after they took ownership of an item that the user owned already and left a
DACL without the right to set an owner, they failed to set the same owner
back
- Fix `InheritedFrom` of `Get-NTFSAccess` and `Get-NTFSAudit` for an entry
whose folder Windows cannot name, such as for an item that was deleted
after it was read or a folder above it that the user cannot read: the text
read `unknown paren`, and the explicit entries showed it as well. An
fix: pass on what a later command raises, and return every item for -Filter *.* A throw in a later command, or an error with -ErrorAction Stop, reaches a cmdlet through its Write call as an ordinary exception. The catch for the failures of an item reported it as the error of that item and went on, so that Remove-Item2 -PassThru removed the next item after a throw, and the caller never saw the exception. The earlier check found only the end of the pipeline and a break or continue. BaseCmdlet now notes the exception that its WriteObject, WriteVerbose, and WriteDebug raised, and every catch that can enclose a write passes it on; Get-DiskSpace writes outside its try. Set-NTFSSecurityDescriptor and Get-FileHash2 also caught it at a verbose message. Get-ChildItem2 -Filter *.* returns every item, as Get-ChildItem does. The cmdlet compared each name with the pattern again and dropped the items without a dot, most folders among them; the dot stays an ordinary character in other patterns. The failed lookup of InheritedFrom frees its native buffer. The help paragraph of -Filter has no pair of asterisks, which platyPS turns into emphasis, and the page has an example for *.*. Review of the independent pass: the restored-owner test asserts that a plain write is denied, the drive-mapping helper has guard tests and takes letters that the no-volume tests do not, and the pipeline tests cover a throw, an error with -ErrorAction Stop, and the verbose and debug streams for every cmdlet that can reach the code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
inherited entry now shows `unknown parent`, and an explicit entry no source;
the failed lookup no longer leaks its native buffer
- Fix `Remove-Item2`, `Copy-Item2`, `Move-Item2`, `Set-NTFSOwner`,
`Set-NTFSSecurityDescriptor`, `Get-NTFSSecurityDescriptor`,
fix: pass on what a later command raises, and return every item for -Filter *.* A throw in a later command, or an error with -ErrorAction Stop, reaches a cmdlet through its Write call as an ordinary exception. The catch for the failures of an item reported it as the error of that item and went on, so that Remove-Item2 -PassThru removed the next item after a throw, and the caller never saw the exception. The earlier check found only the end of the pipeline and a break or continue. BaseCmdlet now notes the exception that its WriteObject, WriteVerbose, and WriteDebug raised, and every catch that can enclose a write passes it on; Get-DiskSpace writes outside its try. Set-NTFSSecurityDescriptor and Get-FileHash2 also caught it at a verbose message. Get-ChildItem2 -Filter *.* returns every item, as Get-ChildItem does. The cmdlet compared each name with the pattern again and dropped the items without a dot, most folders among them; the dot stays an ordinary character in other patterns. The failed lookup of InheritedFrom frees its native buffer. The help paragraph of -Filter has no pair of asterisks, which platyPS turns into emphasis, and the page has an example for *.*. Review of the independent pass: the restored-owner test asserts that a plain write is denied, the drive-mapping helper has guard tests and takes letters that the no-volume tests do not, and the pipeline tests cover a throw, an error with -ErrorAction Stop, and the verbose and debug streams for every cmdlet that can reach the code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
`Get-NTFSSimpleAccess`, `Get-FileHash2`, `Get-DiskSpace`, and
`Get-ChildItem2` below the first folder, which went on with the next item
when a later command ended the pipeline: a `break` or `continue`,
`Select-Object -First`, or a `throw` was handled as a failure of the item,
so that `Remove-Item2 -PassThru | Select-Object -First 1` removed every
fix: pass on what a later command raises through the error stream, and disable an interrupted privilege Get-ChildItem2 swallowed what a later command threw for the error of a nested folder, for example `Get-ChildItem2 -Recurse 2>&1 | ForEach-Object { throw 'x' }`: the recursion took it for a failure of the folder above, wrote a verbose message, and left the loop over the folders, so the listing ended early and the caller never saw the exception. BaseCmdlet now notes the exception that WriteError raises, as it does for WriteObject, WriteVerbose, and WriteDebug. The report that -ErrorAction Stop is swallowed there too was not reproducible (the error reaches the caller), and a break or Select-Object -First was already passed on by type; the tests keep both. A cmdlet that enables the privileges wrote the debug message "..enabled" before it noted the privilege, so a later command that ended the pipeline or threw at that message left the privilege enabled: Dispose disables only what is noted. TryEnablePrivilege also took the exception of a later command for a failure to enable the privilege and went on with the next one, so `Get-NTFSOwner 5>&1 | ForEach-Object { if ($_.Message -eq '..enabled') { throw 'x' } }` enabled all four privileges and hid the exception. The privilege is noted before the message, and TryEnablePrivilege passes the exception on. Red before the fix in the Release build of 7aa8315: three tests (the throw on the error stream, in four configurations the first, in the two elevated ones the two privilege tests). Also covers the typed-throw rows that fail if PowerShell stops wrapping a thrown exception, and Enable-Privileges in a script named NTFSSecurity.Init.ps1. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
item, and the caller never saw the `throw`. The same held when the later
command took a stream instead of the objects: the verbose messages of
`Get-FileHash2` and `Set-NTFSSecurityDescriptor`, the debug messages of
`Set-NTFSOwner`, and the errors of `Get-ChildItem2` for a folder that it
cannot read, for example with `4>&1` or `2>&1`. They now stop and write no
fix: pass on what a later command raises, and return every item for -Filter *.* A throw in a later command, or an error with -ErrorAction Stop, reaches a cmdlet through its Write call as an ordinary exception. The catch for the failures of an item reported it as the error of that item and went on, so that Remove-Item2 -PassThru removed the next item after a throw, and the caller never saw the exception. The earlier check found only the end of the pipeline and a break or continue. BaseCmdlet now notes the exception that its WriteObject, WriteVerbose, and WriteDebug raised, and every catch that can enclose a write passes it on; Get-DiskSpace writes outside its try. Set-NTFSSecurityDescriptor and Get-FileHash2 also caught it at a verbose message. Get-ChildItem2 -Filter *.* returns every item, as Get-ChildItem does. The cmdlet compared each name with the pattern again and dropped the items without a dot, most folders among them; the dot stays an ordinary character in other patterns. The failed lookup of InheritedFrom frees its native buffer. The help paragraph of -Filter has no pair of asterisks, which platyPS turns into emphasis, and the page has an example for *.*. Review of the independent pass: the restored-owner test asserts that a plain write is denied, the drive-mapping helper has guard tests and takes letters that the no-volume tests do not, and the pipeline tests cover a throw, an error with -ErrorAction Stop, and the verbose and debug streams for every cmdlet that can reach the code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
error, and the error of the later command reaches the caller
- Fix the cmdlets that enable the privileges for the duration of their
command, which left a privilege enabled in the session and hid the
exception of a later command when that command took the debug message
after the enabling, for example with `5>&1 | Select-Object -First 2`; they
now disable the privilege and pass the exception on
- Fix the 17 cmdlets that take ownership of an item to retry a denied read or
change and then set the previous owner back: the `Add-`, `Remove-`, and
`Clear-` cmdlets for access and audit entries, `Get-NTFSAccess`,
`Get-NTFSOrphanedAccess`, `Get-NTFSEffectiveAccess`, the six inheritance
cmdlets, `Get-FileHash2`, and `Set-NTFSSecurityDescriptor`. When a later
command in the pipeline threw at the `RestoreOwnerError` that setting the
owner back can write, they reported the exception as the error of the item
and went on with the next one, so that the caller never saw it; they now
pass it on
- Fix `Get-ChildItem2 -Filter`, which read a bracket as the start of a
character class, so that it did not return a file with brackets in its name,
fix: pass on what a later command raises, and return every item for -Filter *.* A throw in a later command, or an error with -ErrorAction Stop, reaches a cmdlet through its Write call as an ordinary exception. The catch for the failures of an item reported it as the error of that item and went on, so that Remove-Item2 -PassThru removed the next item after a throw, and the caller never saw the exception. The earlier check found only the end of the pipeline and a break or continue. BaseCmdlet now notes the exception that its WriteObject, WriteVerbose, and WriteDebug raised, and every catch that can enclose a write passes it on; Get-DiskSpace writes outside its try. Set-NTFSSecurityDescriptor and Get-FileHash2 also caught it at a verbose message. Get-ChildItem2 -Filter *.* returns every item, as Get-ChildItem does. The cmdlet compared each name with the pattern again and dropped the items without a dot, most folders among them; the dot stays an ordinary character in other patterns. The failed lookup of InheritedFrom frees its native buffer. The help paragraph of -Filter has no pair of asterisks, which platyPS turns into emphasis, and the page has an example for *.*. Review of the independent pass: the restored-owner test asserts that a plain write is denied, the drive-mapping helper has guard tests and takes letters that the no-volume tests do not, and the pipeline tests cover a throw, an error with -ErrorAction Stop, and the verbose and debug streams for every cmdlet that can reach the code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
such as `Report[1].txt`, for that name; only `*` and `?` are wildcards. A
null `-Filter` is rejected as a parameter error
- Fix `Get-ChildItem2 -Filter *.*`, which returned only the items with a dot
in their names and dropped the other files and folders, most folders among
them, instead of every item as `Get-ChildItem` does
fix(help): ship the generated help file so Get-Help works (#93) * fix(help): ship the generated help file so Get-Help works Get-Help showed only the syntax of the cmdlets: the module shipped a pre-4.x MAML file for the old command names under the wrong name (NTFSSecurity-Help.xml), while PowerShell looks for en-US\NTFSSecurity.dll-Help.xml. - Generate en-US\NTFSSecurity.dll-Help.xml from Docs/Cmdlets with New-ExternalHelp and commit it. The csproj copies it to the output, so every build ships it, including the local Debug builds that releases are published from. - List all runtime files, including the help file, in FileList. - Remove the stale NTFSSecurity-Help.xml and the unused help editor project NTFSSecurity\Help\NTFSSecurity.Help.pshproj. - Add Tests\Help.Tests.ps1 (Pester 5): Get-Help shows the synopsis, parameters, examples, and online link of every page, and Get-Help -Online resolves to the GitHub page. - Reword six sentences in five cmdlet pages so that each link ends its sentence: platyPS drops the space after a link in the help text. - CI regenerates the help file and fails when it differs from the committed file, then runs the Pester tests. - Document the regeneration step and the link rule in the contributor guide. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: report each Pester test once on AppVeyor AppVeyor build 54834154 passed all 218 Pester tests but listed 870 on its Tests tab: the NUnit import files a Pester 5 test under every block that contains it (Pester, test file, Describe, and Context). Report the results through the build worker API instead (POST api/tests/batch): one entry per test with its outcome, duration, and error message. Outside AppVeyor, and when no test ran, the step sends nothing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
- Fix `Get-Help`, which showed only the syntax: ship the help file
`en-US\NTFSSecurity.dll-Help.xml` generated from the cmdlet documentation,
including the links that `Get-Help -Online` opens, instead of the outdated
`NTFSSecurity-Help.xml`
Ai/docs alignment (#91) * chore: initialize the memory bank Add the canonical .memory-bank base with evidence-based project context: purpose and scope, workflows, stack and validation commands, architecture map, decisions, and the open work found while documenting the cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * docs: align documentation with the cmdlet source - Fill all 36 platyPS cmdlet pages from the C# source: synopsis, description, parameters, defaults, examples, inputs, outputs, and notes, including documented limitations of the current code - Check every example against live parameter metadata and run them in a sandbox; fix examples that did not work (CSV restore, account filter, recursive inheritance, -AccessRights typos) - Rewrite the home, concepts, examples, README, and contributor pages; add a grouped cmdlet overview, module settings, privileges, long paths, and the platyPS workflow - Document Remove-Item2 -PassThru as renamed after 4.2.6 (#64) - Fix mkdocs.yml navigation, edit_uri, and copyright markup; add build.os and a pinned MkDocs version for Read the Docs - Point online help links to the pages on GitHub; add CHANGELOG.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: build the module and check the docs against the build The documentation check ran Update-MarkdownHelp against the NTFSSecurity release from the PowerShell Gallery (4.2.6), so it failed for every unreleased parameter change. PR #91 failed because 4.2.6 still has Remove-Item2 -PassThur while the source and the docs have -PassThru. - Build NTFSSecurity.csproj in Release on the Visual Studio 2022 image, using the .NET Framework 4.5.2 reference assemblies package instead of an installed targeting pack - Check Docs/Cmdlets against the module built from source - Pin platyPS 0.14.2 and MarkdownLinkCheck 0.2.0, and enable TLS 1.2 so the NuGet provider bootstrap works Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * chore: record the green PR 91 build in the memory bank Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
- Fix documentation examples that did not work, such as restoring
permissions from a CSV file and filtering entries by account
- Remove `Show-NTFSSimpleAccess`, which no longer exists, and duplicate
entries from the cmdlets that the module manifest exports and the
PowerShell Gallery lists
- Fix `Set-NTFSInheritance`, which failed with "Nullable object must have a
value" when `-AccessInheritanceEnabled` or `-AuditInheritanceEnabled` was
omitted; an omitted parameter now leaves its section unchanged
- Fix `Get-ChildItem2`, which stopped with an `InvalidCastException` when
`-Path` pointed to a file; it now returns the file, like `Get-ChildItem`
- Fix `Get-FileHash2`, which stopped at a folder in `-Path` and didn't hash
the files that followed it; folders are now skipped
- Fix `Get-NTFSAudit`, which returned nothing without the Security privilege
instead of an error, and which returned the entries of the previous item
again after a path whose security descriptor it couldn't read; it also no
longer takes ownership of an item whose audit entries it can't read, which
didn't help and could leave the owner changed
- Fix `Get-NTFSAccess`, which returned the entries of the previous item again
after a path whose ACL it couldn't read
- Fix `Add-NTFSAudit`, whose `-Account` and `-AccessRights` parameters were
both at position 2, so that positional calls failed; `-AccessRights` is
now at position 3, like in `Remove-NTFSAudit`
([#4](https://github.com/raandree/NTFSSecurity/issues/4))
- Fix `-PassThru` of `Add-NTFSAudit` with `-SecurityDescriptor` and of
`Remove-NTFSAudit` with `-Path`, which returned access entries; both now
return the audit entries
- Fix the `InheritanceEnabled` property of audit entries, which reported the
inheritance of the access entries; it now reports whether the audit
entries are inherited
- Fix `Get-NTFSInheritance -SecurityDescriptor`, which reported
`AuditInheritanceEnabled` as `$true` for a security descriptor that was
read without its audit section; it now reports `$null`, like `-Path`
fix(security): report one audit inheritance by path and by descriptor The module's own tests ran on Windows Server 2019, 2022, and 2025 and on Windows 11 in the operating-system matrix. Two tests failed on every domain-joined machine and passed on the development host: - Get-NTFSInheritance -SecurityDescriptor reported AuditInheritanceEnabled as $false for an item without audit entries, where -Path reported $true. On these computers Windows reports the SACL as protected from inheritance when it reads all sections together, and as not protected when it reads the SACL alone. The descriptor now takes the audit section from a separate read, like it already did for the access section. Write() stores the sections that were read, so a descriptor with the wrong flag would also have written the SACL back as protected. - Get-NTFSEffectiveAccess -ServerName '' wrote an "Access is denied" error on computers where Windows takes an empty name for this computer. An empty name no longer asks the remote interface of the authorization manager; the cmdlet warns and returns the result of this computer, like for any name that can't be reached. The existing tests that found them stay as the regression guards: they were red on three virtual machines (Windows Server 2022 and 2025, Windows 11) and are green after the change. Three tests are new: the audit state of a file and a folder without audit entries, and of a file and a folder with disabled audit inheritance, by path and by descriptor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
- Fix `Get-NTFSInheritance -SecurityDescriptor` for an item without audit
entries on computers where Windows reports its audit entries as protected
from inheritance when it reads all sections of the security descriptor at
once, as it did on domain-joined Windows Server 2022 and 2025 and on
Windows 11: the cmdlet reported `AuditInheritanceEnabled` as `$false`,
while `-Path` reported `$true`. The descriptor now takes the state of the
audit entries from a read of that section alone, like `-Path`, and the
cmdlets that start from such a descriptor no longer see the audit entries
as protected
- Fix `Get-NTFSEffectiveAccess -ServerName ''`, which wrote an "Access is
denied" error instead of the warning for a computer that can't be reached,
on computers where Windows takes an empty name for this one. An empty name
never asks the remote interface of the authorization manager now: the
cmdlet warns and returns the result of this computer on every computer
fix(effective-access): answer a user who isn't an administrator for this computer On a computer in a domain, Get-NTFSEffectiveAccess wrote "Access is denied" and no result for every user who wasn't an administrator of the computer, also for the default -ServerName localhost and for every other name of this computer. The remote interface of the authorization manager of a computer answers only its administrators and the members of Access Control Assistance Operators, and a computer in a domain offers that interface to every caller. On a computer outside a domain the interface is not reachable, so the cmdlet already used the local authorization manager there, which is why the tests passed on the development host and on the CI runners. For a name of this computer, the cmdlet now uses the local authorization manager when the remote one refuses the user. That manager is the one the name asks for, and it answered correctly in every probe on Windows Server 2019, 2022, and 2025 and on Windows 11: for a standard domain user, a local standard user, and an administrator with a filtered token, for the user's own account, Everyone, the Administrator of the computer, and the Administrator and Domain Users of the domain. For the name of another computer, the denial stays an error, as the cmdlet page and the live test of the delegated account describe. Twenty tests of the suite failed in the basic-user mode on every domain-joined machine of the operating-system matrix, with the published 5.0.0-rc7 code and with the code before this change, and pass with it (Windows Server 2019: basic user 782 and 780 passed, 0 failed, in Windows PowerShell and PowerShell 7). A new live test runs the case as the administrator of the file server, who isn't an administrator of the client. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
- Fix `Get-NTFSEffectiveAccess` for a user who isn't an administrator on a
computer in a domain. For a name of this computer, such as the default
`localhost`, the cmdlet wrote the error "Access is denied" and no result for
every account, because the remote authorization manager of a computer
answers only its administrators and the members of Access Control Assistance
Operators. It now uses the local authorization manager of this computer when
the remote one refuses the user, as it already did when the remote one can't
be reached. For the name of another computer, the error stays
- Fix `Get-NTFSEffectiveAccess`, which returned no access and no error when
Windows refused to start the authorization manager for the computer of
`-ServerName`, for example for a name of 32,718 characters or more: the
result looked like an account without any rights. The cmdlet now writes
a `GetEffectiveAccessError` with the error that Windows reported and
returns no result, as it does when a later step of the calculation fails.
The warning that the result is based on this computer now comes only when
the cmdlet calculated a result; it also came before an error when the
computer couldn't be reached
- Fix `Get-NTFSOwner`, which wrote a "The pipeline has been stopped" error
for every path when a command such as `Select-Object -First 1` stopped the
pipeline, and which repeated a failed read instead of reporting the
denied access
- Fix `Copy-Item2`, which failed with a `DirectoryNotFoundException` when it
copied a folder that contained files
- Fix `Disable-Privileges`, which couldn't disable the privileges when the
module setting `EnablePrivileges` was `$false`
- Fix the inheritance cmdlets, which enabled the Backup, Restore, Take
Ownership, and Security privileges even when the module setting
`EnablePrivileges` was `$false`, and left them enabled
- Fix the `Inherits` column of the `Get-ChildItem2` output, which showed
`True` for every item, also for items whose inheritance is disabled
- Fix `Add-NTFSAccess`, `Remove-NTFSAccess`, `Add-NTFSAudit`, and
`Remove-NTFSAudit`, which failed with "Parameter set cannot be resolved"
for `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or
`-PropagationFlags`; `-AppliesTo` is now mandatory in the `Simple`
parameter sets, so such a command uses the flag parameters and their
defaults, as for a path
- **Breaking:** fix `Add-NTFSAccess`, `Remove-NTFSAccess`, `Add-NTFSAudit`, and
`Remove-NTFSAudit`, which ignored the `AppliesTo` property of an object
fix(access,audit): keep the scope of a piped object from reaching the next one Independent review of 93ed2c7: ProcessRecord of Add-NTFSAccess, Remove-NTFSAccess, Add-NTFSAudit, and Remove-NTFSAudit wrote the scope that it converts from AppliesTo into the fields behind InheritanceFlags and PropagationFlags. PowerShell resets only the parameters that the previous piped object bound, so the next object that had no scope, or only one flag, took the scope of the one before it: AppliesTo ThisFolderOnly, then none gave None/None twice, and Remove left the InheritOnly part of every entry. Without the default set (93ed2c7) a piped path object with AppliesTo reaches that code; for a piped -SecurityDescriptor object it was a defect of rc7 already. The flags of a record are locals now. The loop of the two Remove cmdlets converted the scope a second time into the same fields; the locals make that redundant, so it is gone. The tests pipe objects with and without a scope, a CSV file, and descriptor objects into the four cmdlets: red on the build of 93ed2c7 (8 of 87 cases of the two files, in every elevated configuration; 4 in the basic-user ones, where the audit rows skip), green on this build. An empty AppliesTo cell fails to bind for that row only; a test pins it. The Remove-NTFSAudit PathSimple row cannot tell the sets apart (its entry is on a file), and its comment says so. Docs/Examples.md no longer says that a scope is needed so that PowerShell can choose the parameter set (true before 5.0.0 only); the changelog entry names the new errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
piped to them with a path and used the default scope, and which gave a
piped security descriptor object that had only `InheritanceFlags` or
`PropagationFlags` the scope of the object before it; the property now sets
the scope of its own object only. A piped
fix(access,audit): keep the scope of a piped object from reaching the next one Independent review of 93ed2c7: ProcessRecord of Add-NTFSAccess, Remove-NTFSAccess, Add-NTFSAudit, and Remove-NTFSAudit wrote the scope that it converts from AppliesTo into the fields behind InheritanceFlags and PropagationFlags. PowerShell resets only the parameters that the previous piped object bound, so the next object that had no scope, or only one flag, took the scope of the one before it: AppliesTo ThisFolderOnly, then none gave None/None twice, and Remove left the InheritOnly part of every entry. Without the default set (93ed2c7) a piped path object with AppliesTo reaches that code; for a piped -SecurityDescriptor object it was a defect of rc7 already. The flags of a record are locals now. The loop of the two Remove cmdlets converted the scope a second time into the same fields; the locals make that redundant, so it is gone. The tests pipe objects with and without a scope, a CSV file, and descriptor objects into the four cmdlets: red on the build of 93ed2c7 (8 of 87 cases of the two files, in every elevated configuration; 4 in the basic-user ones, where the audit rows skip), green on this build. An empty AppliesTo cell fails to bind for that row only; a test pins it. The Remove-NTFSAudit PathSimple row cannot tell the sets apart (its entry is on a file), and its comment says so. Docs/Examples.md no longer says that a scope is needed so that PowerShell can choose the parameter set (true before 5.0.0 only); the changelog entry names the new errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
object that has `AppliesTo` and `InheritanceFlags` or `PropagationFlags`
now fails with `AmbiguousParameterSet`, like the same parameters on the
command line, and so does an object that has both `Path` and
`SecurityDescriptor`, where the path won before. The empty cell of a CSV
file, `$null`, and `DBNull` count as a value of the other group here,
because PowerShell binds them to the parameters of both groups: a file
that has columns of both groups fails for a row that leaves one of them
empty, so give such a file the columns of one group only. An `AppliesTo`
that is `$null` fails to bind for that object (a row of a CSV file that has
fewer fields than its header gives `$null`). A value that PowerShell can't
convert to a scope, such as the empty cell of a CSV file or a misspelled
name, is an error for that object, see the next entry. A call with
neither `-Path` nor `-SecurityDescriptor` now fails with
`AmbiguousParameterSet` instead of a missing-parameter error for `-Path`
- Fix `Add-NTFSAccess`, `Remove-NTFSAccess`, `Add-NTFSAudit`, and
`Remove-NTFSAudit`, which silently used the default when a piped object had
a value of `AccessType` (`AuditFlags` for the audit cmdlets),
`InheritanceFlags`, `PropagationFlags`, or `AppliesTo` that PowerShell
could not convert, such as a misspelled name or the empty cell of a CSV
file: a typo for `Deny` created an `Allow` entry, and a misspelled scope
used the default scope, without a message. The cmdlets now write the
non-terminating error `InvalidParameterValue` for that object, change
nothing for it, and go on with the next one; a blank value is such an
error too, where it used the default. **Breaking:** the five parameters
have the type `Object`, because the cmdlets convert the values themselves.
A bad value that you name on the command line, and a named `$null`, still
stop the command, but with the error id `InvalidParameterValue`, not the id
of a parameter binding error; `-AppliesTo $null` keeps the error of the
binder, because the parameter is mandatory. `-AccessType` and `-AppliesTo`
take one value: a comma list or a collection of several values is an
`InvalidParameterValue` error, where PowerShell combined the numbers of the
values bit by bit, so that `-AppliesTo 'ThisFolderOnly,FilesOnly'` created a
`FilesOnly` entry and `-AccessType 'Allow,Deny'` a `Deny` entry. A script
block, such as `-AccessType { 'Deny' }`, is no longer evaluated for every
piped object and is a bad value. `Get-Help` shows the type `Object`, and
tab completion still offers the valid names
- **Breaking:** fix `Add-NTFSAccess`, `Remove-NTFSAccess`, `Add-NTFSAudit`, and
`Remove-NTFSAudit` with `-SecurityDescriptor`, which ended the whole
command with a terminating error when the change of one descriptor failed,
such as for a deny entry without rights; they write the non-terminating
error `AddAceError` or `RemoveAceError` for that descriptor and go on with
the next one, as they do for a path. A script that relies on the stop needs
`-ErrorAction Stop`
- Fix `Get-NTFSEffectiveAccess`: `-ExcludeNoneAccessEntries` now leaves out
items without access, the cmdlet uses the current location when `-Path`
is omitted, and `-SecurityDescriptor` returns the effective access of the
security descriptor; before, all three returned nothing or ignored the
parameter
- Fix `Get-NTFSOrphanedAccess`, `Get-NTFSOrphanedAudit`, and
`Get-NTFSSimpleAccess`, which ignored `-Account` and `-SecurityDescriptor`;
`Get-NTFSOrphanedAudit` now writes one object per entry instead of one
collection per item, `Get-NTFSOrphanedAccess` no longer repeats the entries
of the previous item after a failed read, and the output of
`Get-NTFSSimpleAccess` has a table view
- Restore the `-RemoveSpecific` switch of `Remove-NTFSAccess`, which version
4.1 introduced but later versions lacked, and add it to `Remove-NTFSAudit`:
with it, the cmdlets remove only an entry that matches exactly
- Fix `Copy-Item2`, `Move-Item2`, and `Remove-Item2`, which skipped the
remaining paths of `-Path` after a path that didn't exist or, for copy and
move, a file that already existed at the destination
- Fix `Remove-NTFSAccess` and `Remove-NTFSAudit`, which went on with a path
that didn't exist, wrote a second, misleading `RemoveAceError`, and with
`-PassThru` stopped with a `NullReferenceException`
- Fix `-PassThru` of `Enable-NTFSAccessInheritance`,
`Disable-NTFSAccessInheritance`, `Enable-NTFSAuditInheritance`,
`Disable-NTFSAuditInheritance`, and `Set-NTFSInheritance`, which returned
the unchanged state of an item also when the change failed, so that the
inheritance looked disabled
([#74](https://github.com/raandree/NTFSSecurity/issues/74))
- Fix the error of `New-NTFSHardLink` for a missing `-Target`, which said
that the target path existed
- Fix `Get-FileHash2`, which wrote a result for a file that it couldn't
read, with the hash of the previous file
- Fix `-PassThru` of `Add-NTFSAccess`, `Add-NTFSAudit`, `Remove-NTFSAccess`,
and `Remove-NTFSAudit`, which returned the unchanged entries of an item
also when the change failed
- Fix the cmdlets that take ownership of an item to repeat an operation that
was denied: when the second attempt failed as well, the account that ran
the cmdlet stayed the owner of the item; now the previous owner is restored
- Fix `-PassThru` of `Enable-Privileges` and `Disable-Privileges`, which
wrote the privileges as one collection instead of one object per
privilege, and of `New-NTFSSymbolicLink`, which returned a file object for
a link to a folder
- Declare the output types of `Test-Path2`, `Get-FileHash2`,
`Add-NTFSAudit`, `Remove-NTFSAudit`, `Copy-Item2`, `Move-Item2`,
`Remove-Item2`, and the inheritance cmdlets correctly, so that
`Get-Command` and tab completion report the objects they write
- Fix the verbose messages of `Copy-Item2` and `Move-Item2`, which named the
source path as the destination, and of `Disable-Privileges`, which said
that the privileges were enabled, and the spelling of the privilege in
the warning of `Get-NTFSEffectiveAccess`
- Fix `-PassThru` of `Copy-Item2`, `Move-Item2`, and `Remove-Item2`, which
wrote the item also when `-WhatIf` or a declined confirmation skipped the
operation
- Fix `Get-FileHash2` in PowerShell 7, where it failed for every algorithm;
`RIPEMD160` and `MACTripleDES`, which .NET lacks there, now stop the
cmdlet with an error that names the algorithm and points to Windows
PowerShell 5.1
- Fix a `FormatException` in the cmdlets for a path with braces, such as
`C:\Data\{Archive}`: their messages formatted the path a second time
([#3](https://github.com/raandree/NTFSSecurity/issues/3))
- Fix a `NullReferenceException` in every cmdlet when a variable named
`PWD` in the scope of the caller, such as a loop variable, hid the
automatic variable; the cmdlets now read the current location from the
session, and only for a relative path
([#86](https://github.com/raandree/NTFSSecurity/issues/86))
- Fix file and folder objects passed by position, such as
`Get-NTFSOwner $folder`, which Windows PowerShell bound as the name of the
item, so the cmdlets looked for it in the current location
([#88](https://github.com/raandree/NTFSSecurity/issues/88))
- Fix `Remove-NTFSAccess` for an entry with a generic right such as
`GenericAll`, which Windows keeps in the inherit-only entries of folders;
it failed with "The value '269484032' is not valid"
([#17](https://github.com/raandree/NTFSSecurity/issues/17))
fix: change the audit inheritance of items without audit entries 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>
4 weeks ago
- Fix `Enable-NTFSAuditInheritance`, `Disable-NTFSAuditInheritance`, and
`Set-NTFSInheritance -AuditInheritanceEnabled`, which failed with "Access
is denied" for a file or folder without audit entries, also in an elevated
session with the Security privilege
fix: write only the sections of the security descriptor that a cmdlet changes 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>
4 weeks ago
- Fix `Add-NTFSAccess`, `Remove-NTFSAccess`, `Clear-NTFSAccess`,
`Add-NTFSAudit`, `Clear-NTFSAudit`, `Enable-NTFSAccessInheritance`,
`Disable-NTFSAccessInheritance`, and `Set-NTFSInheritance`, which wrote the
owner of an item back with the entries they changed; where the account may
not assign that owner, such as on some file servers, they failed with
"(1307) This security ID may not be assigned as the owner of this object".
They now write only the DACL or the SACL
([#34](https://github.com/raandree/NTFSSecurity/issues/34))
- Fix `Add-NTFSAccess`, `Add-NTFSAudit`, and `Clear-NTFSAudit`, which in an
elevated session could store the inherited access entries of an item as
explicit entries, and `Get-NTFSSecurityDescriptor`, which could return
them without their inherited flag, so that `Set-NTFSSecurityDescriptor`
stored them as explicit entries as well
- Fix `Clear-NTFSAudit`, which finished without an error but changed nothing
in a session without the Security privilege; it now writes an error, like
the other audit cmdlets
- Fix the cmdlets for the root of a drive, such as `C:\`, or of a volume,
such as `\\?\Volume{GUID}\`, which read and changed the security
descriptor of the drive, a device object, instead of that of its root
folder, so that `Get-NTFSAccess` showed other entries than Explorer
([#41](https://github.com/raandree/NTFSSecurity/issues/41))
fix: drive roots, audit descriptors, -WhatIf conflicts, and small items - #41: for the root of a drive, the cmdlets read and changed the security descriptor of the drive, a device object. FileSystemSecurity2 now routes drive roots through the path-based AlphaFS methods, which keep the trailing backslash; the removal and inheritance helpers use it too. - #109: Add-, Remove-, and Clear-NTFSAudit report a security descriptor without the audit entries like Get-NTFSAudit, through one helper, and Get-NTFSEffectiveAccess names the cause that Windows reported instead of a missing Security privilege. - #108: Copy-Item2 and Move-Item2 check the destination only for an operation that runs; with -WhatIf, a verbose message names the conflict. - #111: Disable-Privileges skips the privileges that the token doesn't hold, the privilege messages are spelled right, and Get-FileHash2 declares the type name of its objects; 05-Releasing.md documents the release metadata tests. - rc3 review leftovers: Remove-NTFSAudit writes nothing for an item without a SACL, the owner retry of Set-NTFSSecurityDescriptor restores the previous owner in a finally block and keeps an owner that the descriptor sets, and FileSystemSecurity2.Write with another item writes only the sections that were read. Each fix has a test that failed first, in Windows PowerShell 5.1 and PowerShell 7; writing a drive root was checked once on a temporary VHD. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
- Fix `Add-NTFSAudit`, `Remove-NTFSAudit`, and `Clear-NTFSAudit` with a
security descriptor that was read without the audit entries; they now
write an error like `Get-NTFSAudit` instead of changing the missing entries
without one ([#109](https://github.com/raandree/NTFSSecurity/issues/109))
- Fix `Get-NTFSEffectiveAccess`, which blamed a missing Security privilege
for every failure while the privilege wasn't enabled; the error now names
the cause that Windows reported
([#109](https://github.com/raandree/NTFSSecurity/issues/109))
- Fix `Copy-Item2` and `Move-Item2`, which wrote an error with `-WhatIf` when
the destination file existed, so that `-WhatIf -ErrorAction Stop` stopped
the preview; they now name the existing file in a verbose message
([#108](https://github.com/raandree/NTFSSecurity/issues/108))
- Fix `Remove-NTFSAudit`, which failed with "(5) Access is denied" for a file
or folder without audit entries
- Fix `Set-NTFSSecurityDescriptor`, which set the previous owner back after it
had taken ownership to write a descriptor that sets a new owner, so that
the new owner was lost or the write failed with error 1307
- Fix the `Write` method of a `Security2.FileSystemSecurity2` object for
another item, which wrote every section of the descriptor, also an owner
that Windows returns with the DACL; it now writes the sections that the
descriptor was read with
([#34](https://github.com/raandree/NTFSSecurity/issues/34))
- Fix `Disable-Privileges`, which warned that it couldn't disable the
privileges that the access token doesn't hold, and the declared output type
of `Get-FileHash2`, which named the AlphaFS `FileInfo` instead of the type
name of its objects
([#111](https://github.com/raandree/NTFSSecurity/issues/111))
- Fix `Get-NTFSEffectiveAccess`, which returned no access when the computer
of `-ServerName` couldn't be reached, although it warned that it had
calculated the result on this computer; it now returns that result
- Fix `Test-Path2`, which stopped with the terminating error "Illegal
characters in path" in Windows PowerShell for a path with a character
that Windows doesn't allow in names, such as `|`; it now returns `$false`
for such a path, as in PowerShell 7, and writes the reason as a debug
message
- Fix the cmdlets that enable the Backup, Restore, Take Ownership, and
Security privileges for the duration of their command, which left them
enabled in the session when a later command, such as `Select-Object -First`,
or a terminating error stopped the pipeline early; they now disable them
also then. `Enable-Privileges` keeps them enabled by design
- Fix the cmdlets that enable the privileges for the duration of their
command, which stopped with the error
"Priviledge already disabled" and left the other privileges enabled when
another command in the pipeline, such as `Disable-Privileges`, had
disabled one of them; a privilege that they can't disable now gives a
warning, and they still disable the others
- Fix `Get-NTFSSimpleAccess`, which showed no rights for an entry that
grants only `ReadData`, and which left out the parent folder of a
relative path with a single folder name, although `-IncludeRootFolder` is
on by default
- Fix `Copy-Item2` and `Move-Item2`, which didn't detect a folder at the
destination, so that a copy failed in the middle after it had copied a
part of the folder, and which reported a missing destination folder with
an error that named the source item
([#21](https://github.com/raandree/NTFSSecurity/issues/21)); they now
write `DestinationFileAlreadyExists` and an error that names the missing
folder, and with `-WhatIf` a verbose message that names it. `Copy-Item2`
no longer creates the missing folders of the destination when it copies a
folder, which the prereleases of 5.0.0 did
- Fix `Get-NTFSHardLink`, which stopped for all remaining paths at a folder
and at a file on a network share, where Windows can't list the names of
a file, and `New-NTFSHardLink -PassThru`, which stopped with a
terminating error on a share after it had created the link; both now
write a non-terminating `GetHardLinkError`
- Fix `-PassThru` of `Set-NTFSSecurityDescriptor`, which returned nothing
for a descriptor that the cmdlet wrote as the owner, and which turned a
failed read after a successful write into another attempt of the write
and a `WriteSdError`; it now writes a `ReadSecurityError` for that read
- Fix `Get-NTFSOrphanedAccess`, which reported an item that it couldn't
read as an `AddAceError`; it now writes a `ReadSecurityError`, like
`Get-NTFSAccess`
- Fix every cmdlet for a relative path that starts with a dot but not with
`.\`, such as `.gitignore`: the cmdlets dropped its first two characters
and read, changed, or removed the item with the shorter name, such as
`itignore`, when one existed
- Fix comparing the objects of the access, audit, and security descriptor
cmdlets: `-eq` and `-contains`, and in PowerShell 7 also
`Select-Object -Unique` and `Compare-Object`, stopped with an
`InvalidCastException`, and a security descriptor as the key of a
hashtable with a `NullReferenceException`. Two objects are now equal when
they hold the same entry or descriptor, as in .NET. Converting a security
descriptor to `FileSecurity` or `DirectorySecurity` returned `$null`
- Fix `InheritedFrom` of `Get-NTFSAccess` and `Get-NTFSAudit`: with
`-ExcludeExplicit`, each inherited entry showed the source of another
entry, and `Get-NTFSAccess -SecurityDescriptor` stopped with an
`ArgumentOutOfRangeException` for a descriptor with audit entries, such
as one that `Get-NTFSSecurityDescriptor` reads in an elevated session
- Fix `Get-NTFSOrphanedAudit`, which returned nothing without the Security
privilege, as for an item without orphaned entries, and wrote a warning
for an item that it couldn't read; it now writes a `ReadSecurityError`,
like `Get-NTFSAudit`
- Fix `Get-NTFSSimpleAccess`, which left out a folder whose parent folder it
hadn't reported, and with it all of its subfolders, and which compared a
drive root with the parent folder of the folder before it; such folders
are now reported with all of their entries, and a parent folder is found
also when its path differs in case. A folder that came after its parent
folder a second time failed with a `ReadError`
- Fix `Move-Item2` for a folder on another volume, which Windows can't
move: the cmdlet copied and deleted it instead, so that an empty folder
was deleted without being created at the destination, and a folder with
files failed with an error that named one of its files. It now writes a
`MoveError` that names the folder and the destination, and leaves the
folder in place
- Fix `New-NTFSHardLink` and `New-NTFSSymbolicLink`, which failed with
`GetDefaultValueFailed` for every object piped to them, such as the rows
of a CSV file with the columns `Path` and `Target`
- Fix the errors of `New-NTFSSymbolicLink` for an existing `-Path` and a
missing `-Target`, and of `New-NTFSHardLink` for a folder as `-Target`,
which named no path. `New-NTFSSymbolicLink` now checks `-Path` first,
like `New-NTFSHardLink`
- Fix `Get-NTFSEffectiveAccess`, which warned that the result might be
inaccurate for every name of this computer in `-ServerName` except
`localhost` in lowercase, such as `.`, `LOCALHOST`, or the computer name,
where the computer doesn't offer the remote access check
Ai/docs alignment (#91) * chore: initialize the memory bank Add the canonical .memory-bank base with evidence-based project context: purpose and scope, workflows, stack and validation commands, architecture map, decisions, and the open work found while documenting the cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * docs: align documentation with the cmdlet source - Fill all 36 platyPS cmdlet pages from the C# source: synopsis, description, parameters, defaults, examples, inputs, outputs, and notes, including documented limitations of the current code - Check every example against live parameter metadata and run them in a sandbox; fix examples that did not work (CSV restore, account filter, recursive inheritance, -AccessRights typos) - Rewrite the home, concepts, examples, README, and contributor pages; add a grouped cmdlet overview, module settings, privileges, long paths, and the platyPS workflow - Document Remove-Item2 -PassThru as renamed after 4.2.6 (#64) - Fix mkdocs.yml navigation, edit_uri, and copyright markup; add build.os and a pinned MkDocs version for Read the Docs - Point online help links to the pages on GitHub; add CHANGELOG.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * ci: build the module and check the docs against the build The documentation check ran Update-MarkdownHelp against the NTFSSecurity release from the PowerShell Gallery (4.2.6), so it failed for every unreleased parameter change. PR #91 failed because 4.2.6 still has Remove-Item2 -PassThur while the source and the docs have -PassThru. - Build NTFSSecurity.csproj in Release on the Visual Studio 2022 image, using the .NET Framework 4.5.2 reference assemblies package instead of an installed targeting pack - Check Docs/Cmdlets against the module built from source - Pin platyPS 0.14.2 and MarkdownLinkCheck 0.2.0, and enable TLS 1.2 so the NuGet provider bootstrap works Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> * chore: record the green PR 91 build in the memory bank Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
- Fix [Get-ChildItem2](Docs/Cmdlets/Get-ChildItem2.md) with `-Hidden`,
which omitted the first hidden item unless `-Force` was also supplied
- Fix the comparison of an identity with a name by its `Equals` method, such
as `$entry.Account.Equals('nt authority\system')`, in the Turkish culture
(`tr-TR`): it changed the case of both names with the culture of the thread,
which turns `I` into a dotless `ı`, so an account whose name holds an
uppercase `I`, such as `NT AUTHORITY\SYSTEM` or `BUILTIN\Administrators`,
did not match the same name in another case. The operators `-eq`,
`-contains`, and `-in` were not affected
- Fix [Get-ChildItem2](Docs/Cmdlets/Get-ChildItem2.md) with `-Filter` in the
Turkish culture (`tr-TR`), which dropped the items whose names differ from
the filter in the case of an `I`, such as `Index.txt` for `-Filter 'index*'`
or `SETTINGS.INI` for `-Filter '*.ini'`
ci: publish releases from CI on a version tag, starting with 5.0.0-rc1 Pushing a tag such as 5.0.0 or 5.0.0-rc1 on master now publishes the package that the build job built and tested to the PowerShell Gallery and creates the GitHub release with NTFSSecurity.zip. - New-ModulePackage.ps1 copies only the FileList files of the Release build, so no debug symbols, XML documentation, or copy of System.Management.Automation.dll ship. It builds the nupkg with Compress-PSResource and adds the command tags (PSIncludes_Cmdlet, PSCmdlet_*, PSCommand_*) that PSResourceGet leaves out and that the Gallery uses to list cmdlets and that Find-Command searches. Every CI run builds and uploads the packages. - Get-ReleaseInfo.ps1 returns the version and release notes: a dated CHANGELOG section for a release, the [Unreleased] section for a prerelease. - The release job checks that the tag matches the manifest version and points to a commit on master, reads the API key from the environment powershell-gallery, and skips steps already done, so a rerun is safe. - The manifest gets the prerelease label rc1 and a release notes link; the 5.0.0 changelog entries move back to [Unreleased] until the final release. - Tests/Release.Tests.ps1 covers both scripts and the packages; the changelog check moves there from Manifest.Tests.ps1. - Docs/Contributing/05-Releasing.md describes the one-time setup and the release steps; Docs/README.md explains -AllowPrerelease. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
[Unreleased]: https://github.com/raandree/NTFSSecurity/compare/4.2.6...HEAD