-AccessType and -AppliesTo of Add-NTFSAccess, Remove-NTFSAccess,
Add-NTFSAudit (-AppliesTo), and Remove-NTFSAudit (-AppliesTo) take one value,
but PowerShell adds up the numbers of a comma list or an array for an
enumeration, so that -AppliesTo 'ThisFolderOnly,FilesOnly' created a
FilesOnly entry and -AccessType 'Allow,Deny' created a Deny entry, without a
message. The conversion in ParameterConversion now rejects a string with a
comma and a collection of more than one element for an enumeration that is
not a flags enumeration, with the same InvalidParameterValue error as for a
misspelled name (terminating for a named value, one error per object for a
piped one). A single name and a collection of one element convert as before,
and the flags parameters still take a list. The valid-value matrices of both
published rc8 and this build give the same entries in both editions, named,
piped by property name, and splatted, apart from the nine list rows.
The completers of the five parameters compared with WildcardOptions.IgnoreCase
only, so that a word typed in capitals did not complete while the culture of
the thread was Turkish (an I and an i are different letters there, and
THISFOLDERO did not match ThisFolderOnly). They compare culture invariant now,
like the filter of Get-ChildItem2.
The tests pin both, red before the change and green after it in four
configurations, and the headers of the two test files no longer say that the
-SecurityDescriptor sets have no handler per descriptor.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Set the prerelease label to rc9 and add 5.0.0-rc8, which the PowerShell
Gallery has had since 2026-10-20, to the versions that the Gallery has
(Docs/Contributing/05-Releasing.md).
A separate commit, so that it can be dropped if the changes of this branch
go into another prerelease instead.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Regenerate NTFSSecurity.dll-Help.xml from the pages with New-ExternalHelp
and let platyPS wrap the syntax of the four add and remove pages for the
parameters that are Object now. The pages and the file are a fixpoint: after
a rebuild, Update-MarkdownHelp changes no page and New-ExternalHelp changes
no file.
State two sentences more plainly: what a blank value of the other parameter
group does to the four add and remove cmdlets, and where Get-ChildItem2
-Filter differs from the built-in Get-ChildItem in PowerShell 7.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Remove the labels of review findings and the references to probe scripts
and reports that are not in the repository from the comments of the tests
that rc9 adds, and say what each test pins in words that stand alone. Only
comments and the name of one Context in each of two files change; no
assertion does.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
R1-1 (major): the four pages claimed that a blank cell of AppliesTo, AccessType or
AuditFlags, InheritanceFlags, or PropagationFlags is an InvalidParameterValue error
for every shape. That is wrong when the blank, $null, or DBNull value belongs to
the group that -AppliesTo did not select: PowerShell counts a property that is
present, even blank, as offered for choosing the parameter set, the same as a
real value, so AppliesTo together with a blank InheritanceFlags or
PropagationFlags (for example a short CSV row, whose missing trailing columns
Import-Csv fills with $null) is AmbiguousParameterSet, and rc8 created the
entry. The pages now say that a CSV file should have the columns of only one
group, that mixing both groups fails with AmbiguousParameterSet, that a literal
$null named or piped for -AppliesTo itself fails with its own, unrelated,
pre-existing error because -AppliesTo is mandatory, and keep the sentence that a
bad value within the chosen group is InvalidParameterValue.
R1-3 (minor): the pages now also say that a script block is a plain value for
these parameters and is not evaluated once for each piped object the way rc8
evaluated it, so a named script block is a terminating InvalidParameterValue
error.
Neither finding needed a code change; both already read this way. Pinned with
new table-driven tests, over the four cmdlets and their Path and SD parameter
sets, for AppliesTo valid combined with a $null, an empty string, or DBNull
InheritanceFlags or PropagationFlags and the reverse, and for a named script
block of each of the five parameters: the error id the binder already gives,
nothing changed, and, where applicable, the next piped object still processed.
Confirmed unchanged against the pre-R1-2/R1-4 build.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Add the entries for the filter of Get-ChildItem2, the error of
Get-NTFSOrphanedAccess, the position of -SecurityDescriptor of
Set-NTFSSecurityDescriptor, the conversions from FileSecurity and
DirectorySecurity (and what they mean for the cmdlets: Get-Acl objects now
bind), the account list of the RemoveAll methods, the path overloads of the
Add methods, the EnablePrivileges setting, the 17 owner-restore handlers, the
piped values that the add and remove cmdlets could not convert, and the
descriptors of those cmdlets that fail one by one.
Say what the object type of the five parameters costs (a script block is no
longer evaluated per object; an empty value of the other group makes an
object ambiguous) and replace the sentence that said such a value is ignored.
Each statement was checked by a probe against the published rc8 and the build
of this branch, in both editions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Add-NTFSAccess, Remove-NTFSAccess, Add-NTFSAudit, and Remove-NTFSAudit
had the same flaw as the 13 handlers fixed before: when a later command
of the pipeline throws exactly at the RestoreOwnerError record that
InvokeAsOwner writes after a failed restore of the owner, the catch around
the call reported the exception as the item's own AddAceError or
RemoveAceError and went on with the next path, so the caller never saw it.
The four handlers now check IsFromLaterCommand first, like the others, so
all 17 handlers of item 7 of Decision 27 pass the exception on.
The table of Tests\PipelineControl.Tests.ps1 gets two rows, for
Add-NTFSAccess and Remove-NTFSAccess, which use the scenario of the
inheritance cmdlets (a ChangePermissions deny for the user and an owner
that only the Restore privilege can set back). The two audit cmdlets can't
be pinned this way: Windows lets this elevated session write the SACL
whatever the DACL says, so their action never fails to begin with.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The completers for AccessType, AuditFlags, InheritanceFlags,
PropagationFlags, and AppliesTo returned nothing for a quoted word
(-AccessType "D) or a wildcard word (-AppliesTo *Only, -AccessType
D*), which rc8's built-in enum-parameter completion still offered.
PowerShell auto-closes an unterminated quote before it reaches the
completer, so the word a completer receives for -AccessType "D is
"D", not D.
EnumArgumentCompletion.Complete now strips a leading quote and its
matching trailing quote from the word before matching, matches the
enumeration's names with WildcardPattern(word + "*",
WildcardOptions.IgnoreCase) the way PowerShell's own enum completion
does, and, when the word was quoted, returns each match in the same
quote character (CompletionText 'FilesOnly' for a leading single
quote). An unquoted, non-wildcard word is unaffected: appending "*"
to it only turns an exact prefix match into a prefix-wildcard match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
A named $null of AccessType, AuditFlags, InheritanceFlags,
PropagationFlags, or AppliesTo (a literal $null, a variable that holds
$null such as a misspelled property, the alias -AccessControlType,
splatting, or a null entry of $PSDefaultParameterValues) silently kept
the parameter's default instead of stopping: Add-NTFSAccess -AccessType
$null created an Allow entry, Add-NTFSAudit -AuditFlags $null audited
Success and Failure, and Remove-NTFSAccess -AccessType $null removed
nothing. Before the five parameters became object (Decision 27, fix
B), the same named $null ended with a terminating ParameterBindingFailed.
Each cmdlet's BeginProcessing now checks, for a value that is null,
whether MyInvocation.BoundParameters has the parameter's name; a piped
property that is null is not bound yet at that point and still keeps
the default, but a value that is already bound and null is reported
the same way as a bad named value: a terminating InvalidParameterValue
error naming the parameter and its valid values. AppliesTo is Mandatory
and a named $null of it was already a terminating
ParameterArgumentValidationErrorNullNotAllowed from the binder itself,
unchanged by this fix.
ParameterConversion gains the message for this case next to the
existing blank-value message, so that the wording is built in one
place.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
In the four -SecurityDescriptor parameter sets of Add-NTFSAccess,
Remove-NTFSAccess, Add-NTFSAudit, and Remove-NTFSAudit, a change that
throws, such as a Deny entry without rights, ended the cmdlet with a
terminating error, while the -Path parameter sets already wrote an
AddAceError or RemoveAceError for the failing item and went on to the
next one. The two kinds of parameter sets now behave the same way.
Each descriptor's change is wrapped in its own try/catch: a failure
writes a non-terminating AddAceError or RemoveAceError, category
WriteError, that targets the descriptor, and the cmdlet continues
with the next descriptor in the pipeline instead of stopping. -PassThru
stays outside the try, so what a later command raises when the
cmdlet writes its output is never caught there. The existing
TestAuditSection check of the audit cmdlets, and everything else
about a successful change, is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Add-NTFSAccess, Remove-NTFSAccess, Add-NTFSAudit, and Remove-NTFSAudit
silently kept the default value of AccessType, AuditFlags,
InheritanceFlags, PropagationFlags, and AppliesTo when a piped object's
property could not be converted to the parameter's type: a misspelled
AccessType such as "Denyy", or a blank CSV cell, created an Allow entry
with no message. For a permissions tool, a typo for Deny that silently
grants access is a security-relevant defect (Decision 27).
The five parameters are now declared as object and converted inside
the cmdlet, the way the PowerShell binder converts a typed parameter
(names in any case, comma-separated flag lists, numbers, enum
instances). A value that cannot be converted, including a blank one,
is now an error named InvalidParameterValue: terminating and
catchable when it is named on the command line, exactly as the binder
reported it before; a non-terminating error targeting that path or
descriptor when it comes from a piped object, which leaves that item
unchanged and lets the pipeline continue with the next one. A $null
value is still not an error and keeps the parameter's default. Tab
completion of the five parameters keeps working through explicit
argument completers. Choosing between the Simple and Complex
parameter sets is unaffected and still rejects AppliesTo together
with InheritanceFlags or PropagationFlags as AmbiguousParameterSet,
for every mix of string and enum values.
The four cmdlet pages document the parameters as Type: Object, list
the valid values, and describe the new error; a sentence that said a
piped AppliesTo typo or blank cell was silently ignored is corrected.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The coverage record of Handoff 5 listed getters of parameters that take
pipeline input by property name and that no test bound that way: -Destination
of Copy-Item2 and Move-Item2, -Account of Set-NTFSOwner, and -Account of
Get-NTFSEffectiveAccess (the getters of AccessType, AuditFlags, and the scope
and flag parameters of the access and audit cmdlets, and -Algorithm of
Get-FileHash2, are bound by tests now). PowerShell calls the getter of such a
parameter once per command when a piped object binds it, so a test has to
pipe an object that has the property.
Each test pipes two objects that name different values and checks that each
item gets its own: two destinations for the copied and the moved file
(Copy-Item2 and Move-Item2, read back with Get-Content and Test-Path), two
owners that only the Restore privilege can assign (Set-NTFSOwner, read back
with Get-Acl; elevated only), and the effective access of Everyone, which an
allow entry grants, and of Guests, which a deny entry takes away
(Get-NTFSEffectiveAccess).
Tests only; no product change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-NTFSEffectiveAccess already falls back to the local authorization
manager for a name of this computer when the remote one refuses the
caller, which covers every account except a user account of the domain:
Windows still answers "Access is denied" for that one case, because the
local manager has no domain credentials to resolve it. The cmdlet
already writes this as a non-terminating GetEffectiveAccessError and
returns no result for the item; nothing in the behavior changes.
Docs\Cmdlets\Get-NTFSEffectiveAccess.md gets one more NOTES paragraph,
in the style of the neighboring "Before 5.0.0..." paragraphs, saying so
and naming the accounts that still get a result (accounts of this
computer, and domain groups such as Everyone or Domain Users). Evidence:
Tests\Lab\Acceptance-2026-10-10-os-matrix.md, "The probe", row "Local
standard user". No code change; Tests\Help.Tests.ps1 (unchanged) already
covers the page's synopsis, parameters, examples, and links.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Set-NTFSSecurityDescriptor declared -SecurityDescriptor at Position = 2,
its only positional parameter; every sibling that takes a security
descriptor or a path takes its first positional parameter at 1. Moved
to Position = 1 for consistency. A positional call with one argument
already bound to it, because it was the only positional parameter in
its only parameter set, so no script that calls the cmdlet positionally
can notice a difference; this is cosmetic, as Decision 27 describes it.
Tests\SecurityDescriptor.Tests.ps1 adds a characterization-turned-pin
test: the declared Position is 1, and Set-NTFSSecurityDescriptor $sd
still works positionally. RED before the change (Position was 2), GREEN
after, in all four configurations.
Docs\Cmdlets\Set-NTFSSecurityDescriptor.md: Position: 1 in the yaml
block of -SecurityDescriptor.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-NTFSOrphanedAccess wrote a warning ("Could not read item {0}. The
error was: {1}") for a read failure that is not an access denial, while
every sibling (Get-NTFSAccess, Get-NTFSAudit, Get-NTFSEffectiveAccess,
Get-NTFSInheritance, Get-NTFSSecurityDescriptor) writes a non-terminating
error and goes on with the next item. The cmdlet now writes
ReadSecurityError, categorized as OpenError and targeting the path,
through WriteError, then continues, the same pattern
Get-NTFSAccess (GetAccess.cs) already uses for the same kind of failure.
A script that collected this warning with -WarningVariable now has to
read $Error or -ErrorVariable instead.
No existing test pinned the warning (searched for "Could not read item"
and Get-NTFSOrphanedAccess with -WarningVariable across Tests\; none
found), so none needed changing.
NOT DONE: a new test that triggers this exact catch (a read failure that
is not UnauthorizedAccessException) through the public surface. Five
probes (..\probes-wi2\p-orphaned-read-failure*.ps1) tried a sharing
lock, an over-long path, a dangling and a looped junction, and an
alternate data stream; none reached this catch without also failing
GetFileSystemInfo2 first (a different error, ReadFileError) or succeeding
outright, because an elevated session that can read the item at all can
read its ACL as well. The change is still correct and matches the
module's convention; it is defensive code for a condition this harness
cannot construct deterministically.
Docs\Cmdlets\Get-NTFSOrphanedAccess.md documents the new error next to
the existing ReadSecurityError paragraph for the access-denied case.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-NTFSAccess writes ReadSecurityError with category WriteError when a
read succeeds only after the cmdlet takes ownership and the restored
owner is irrelevant to that path; Get-NTFSAudit, Get-NTFSEffectiveAccess,
Get-NTFSInheritance, and Get-NTFSSecurityDescriptor already report the
same failure the same way, so this is the module's convention, unlike
Get-NTFSOrphanedAccess, whose own category for the same failure is
ReadError. No script could notice: the behavior does not change. A
characterization test in Tests\ParameterSets.Access.Tests.ps1, next to
the orphaned-access test that already pins the ReadError side of the
same convention, is green at once and runs in all four configurations.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
InvokeAsOwner (and Set-NTFSSecurityDescriptor's WriteChangesAsOwner) take
ownership of an item, run the action, and in a finally restore the
previous owner, writing a non-terminating RestoreOwnerError through
WriteError when that restore fails. WriteError runs the later commands
of the pipeline while it writes, so in the rare case that a later
command throws exactly when it sees that RestoreOwnerError record (for
example `... 2>&1 | ForEach-Object { if ($_.FullyQualifiedErrorId -like
'RestoreOwnerError,*') { throw } else { $_ } }`), that exception used to
leave InvokeAsOwner through the finally and reach the handler around the
call, which reported it as the item's own error (AddAceError,
ReadSecurityError, ModifySdError, and so on) and moved on to the next
path. The caller never saw the exception.
Thirteen handlers now check IsFromLaterCommand as the first statement of
their catch, the same pattern SetSecurityDescriptor.cs already used in
its second handler and GetSecurityDescriptor.cs already used: Add/Clear
and Get-NTFSAccess, Get-NTFSOrphanedAccess, Get-NTFSEffectiveAccess,
Clear-NTFSAudit, Get-FileHash2, the six inheritance cmdlets, and the
owner-retry of Set-NTFSSecurityDescriptor. The four add/remove access and
audit cmdlets have the same flaw and belong to another work item.
Tests\PipelineControl.Tests.ps1 adds one table-driven It, elevated only,
that denies the current user the right a cmdlet's action needs, gives
the item an owner only the Restore privilege can set back (which the
test turns off), and asserts that a later command's exception reaches
the caller, no item-error record was written for it, and the next path
is untouched. Six of the thirteen handlers are pinned this way (the
other seven need the current user to both fail and succeed the same
access check at once, which Windows does not allow; see the comment
above the Describe block and the probes under ..\probes-wi2\ for the
empirical evidence). The four add and remove cmdlets, which have the same
flaw, follow in the next commit of this item.
Get-NTFSInheritance, the one of the thirteen that writes its result in a
finally, writes it after the try instead, so that the object does not go to
the later command that has just thrown.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
An independent review found that platyPS 0.14.2, which generates the
shipped help file from these pages, pairs up every two literal
asterisks within one paragraph as markdown emphasis and drops them,
even inside backticks: the -Filter parameter description and the
matching paragraph of NOTES each had three or four literal asterisks
in one paragraph, so `Get-Help Get-ChildItem2 -Parameter Filter` and
the NOTES section showed `Report. ` instead of `` Report.* `` and
` . ` instead of a plain asterisk pattern, silently losing the
character that the sentence was about.
Both paragraphs are now several short paragraphs, each with at most
one literal asterisk; a pattern that itself needs more than one
asterisk, such as a plain asterisk, a dot, and an asterisk, is spelled
out in words instead, the way the page already did before this
feature. Verified by running `New-ExternalHelp` from platyPS 0.14.2
into a temporary folder (not the repository's help file) and
confirming every pattern renders intact in the generated XML, then
removing the folder.
The same two paragraphs also said PowerShell 7's own `Get-ChildItem
-Filter` returns nothing for any pattern that ends in a dot and
returns every item only for a pattern of an asterisk, a dot, and one
question mark. Measured directly on PowerShell 7.6.7, both overstated
the difference: a trailing dot returns nothing there only when the
character right before the dot is not an asterisk (a star right
before the dot behaves the same as Windows PowerShell 5.1 and as
Get-ChildItem2 there too), and a pattern of an asterisk, a dot, and
two question marks also returns every item, not only one question
mark. Both paragraphs now say exactly that.
Also removed "(Decision 27, item 4)" from both paragraphs and from two
test comments (the maintainer's agent already removed it from the
integration branch; this avoids a conflicting edit), and changed one
sentence of the DESCRIPTION section that said every -Path value must
name a folder: a value that names a file returns that file, as the
PARAMETERS section and NOTES already said and the cmdlet already did.
No test changes: these are documentation wording changes only, and the
page keeps its existing structure (headings, parameter block, NOTES
list). Re-ran Tests\ItemCmdlets.Tests.ps1 (no code changed in this
commit) to confirm the suite is still green: elevated-Desktop
193/0/0, elevated-Core 192/0/1, basic-Desktop 187/0/6, basic-Core
186/0/7 (passed/failed/skipped), three times, identical.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
An independent review found that a very long -Filter pattern (for
example, a run of 120,000 question marks, or 45,000 asterisks) crashes
the whole host process with an uncatchable StackOverflowException: the
matcher recurses roughly once per character of the pattern, and a long
enough pattern exhausts the stack. A pattern this long serves no
purpose that a shorter one could not also serve, and the review
confirmed that patterns of 32,767 characters or fewer, of any shape
(literal, "?" repeated, "*" repeated, "*?" repeated, "*." repeated),
do not come close to exhausting the stack.
Added `[ValidateLength(0, 32767)]` next to the existing
`[ValidateNotNull]` on -Filter, so that a pattern longer than 32,767
characters is rejected at parameter binding, before it ever reaches
the matcher, with the same `ParameterArgumentValidationError` and
`'Filter'` in the message as the existing null rejection; shorter
values, including an empty one, are unaffected.
Tests (Tests\ItemCmdlets.Tests.ps1, "Get-ChildItem2" > "Recursion, type
filters, and depth"): a -Filter of 32,768 characters now gives
ParameterArgumentValidationError, and one of exactly 32,767 characters
("?" repeated, in a folder with one file) returns the right result
without crashing. The crash itself was confirmed in a disposable child
process (not through the shared Pester harness, to avoid taking that
process down too) with the reviewer's probe
(C:\Temp\ntfs-rc9\review-probes-r3\p9-longpattern.ps1 -N 120000 -Kind
qm): the process terminated with a StackOverflowException before this
fix, and after it, the same probe at the exact boundaries (32,767 and
32,768 characters, every pattern kind the probe offers) neither
crashes nor is accepted past the limit.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
An independent review found that the matcher of Get-ChildItem2 -Filter
(commit 69cd8ed) bounded a star in front of a dot token at the FIRST
dot of the name instead of the LAST one (Win32 DOS_STAR). The
differential oracle of 69cd8ed used only 8.3-compliant names, which
have at most one dot, so the first dot and the last dot are always the
same position there and the bug could not show up. With a name that
has two or more dots, such as "archive.tar.gz" or "jquery.min.js", the
star stopped too early and the rest of the pattern could not reach the
final segment of the name, so a pattern such as "*.?", "*.??", or
"*.?.?" wrongly returned nothing for these names, although Windows
PowerShell 5.1 returns them.
What a user sees changing: -Filter patterns of the shape "a star
followed by a dot" (including "*.?", "*.??", "*.???", a star in a
multi-part pattern such as "a*.?" or "x.*.?") now also match names
with two or more dots, the same as Windows PowerShell 5.1, in both
editions. A name with at most one dot is unaffected (that case was
already correct).
Fixed by bounding the star at `name.LastIndexOf('.')` instead of the
first dot at or after the current position, and corrected the two
comments that described the old, narrower rule.
Also added a discriminating row to the existing short-name test
(`-Filter 'LONGFI~1*'` against a plain file named `LongFileName`,
expected to return nothing): the three rows already in that test
happen to give the same result whether the matcher reads the real
name or the short name, so they could not have caught a regression to
short-name matching; this row can.
Tests (Tests\ItemCmdlets.Tests.ps1, "Get-ChildItem2" > "Recursion, type
filters, and depth"): added a 9-row test with 10 names that have two or
three dots (including the realistic ones from the review: archive.tar.gz,
jquery.min.js, my.file.name.txt, v1.2.3, index.d.ts), expected values
pinned from Windows PowerShell 5.1 with `fsutil file setshortname` (and,
for one row, `fsutil 8dot3name strip`) so that a short name the volume
assigns cannot also produce a match; and the LONGFI~1* row above. Both
fail on the build of 69cd8ed and pass after this fix.
The fix was checked with the reviewer's differential harness
(C:\Temp\ntfs-rc9\review-probes-r3\diff5.ps1) against this build: 0
mismatches over two independent fixtures (732,630 real-name/pattern
pairs with names of two or more dots, short names overridden with
`fsutil file setshortname` so that a hit can only come from the real
name), in addition to the 109,308 pairs of 8.3-compliant names checked
for 69cd8ed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-ChildItem2 -Filter now applies a single matcher, in the cmdlet, that
follows the Win32 "DOS" wildcard rules Windows PowerShell 5.1 applies to
Get-ChildItem -Filter, on the real name of the item, in both editions
(Decision 27, item 4, option B). Before this change the pattern was
matched twice: once by the AlphaFS enumeration and once by the cmdlet
with a WildcardPattern that read a dot as an ordinary character, so the
two editions, and Get-ChildItem itself, disagreed on patterns with a
dot. AlphaFS now always enumerates with "*", and the new matcher decides
alone.
What a user sees changing:
- "Report.*" also returns "Report", which has no dot (previously only
names with a dot matched a pattern ending in ".*").
- A pattern that ends in a dot, such as "Report." or "Rep*.", now
returns the names without a dot, instead of nothing.
- "*.*.*" now returns every item, the same as "*.*" and a plain "*",
instead of only names with two literal dots.
- Breaking: an empty -Filter ('') now returns every item, like no
filter at all, instead of nothing. This matches the policy of
Windows PowerShell 5.1 for every other dot pattern; a script that
relied on an empty -Filter returning nothing should pass -Filter '*'
explicitly to keep that behavior from before.
- A single dot ('.') as -Filter also returns every item, matching
Get-ChildItem.
- Get-ChildItem2 deliberately no longer follows PowerShell 7's own
Get-ChildItem -Filter for a pattern that ends in a dot (which there
returns nothing) or for "*.?" (which there returns every item): it
follows the Windows PowerShell 5.1 rules in both editions instead, so
the two editions of Get-ChildItem2 agree with each other.
- Unaffected: -Filter matching by the real name and not the 8.3 short
name, brackets and backticks as ordinary characters, case-insensitive
matching with the invariant culture, the null-Filter error, and every
other parameter and its interaction with -Filter.
The matcher was derived and checked against a differential oracle of
real Windows PowerShell 5.1 Get-ChildItem -Filter runs: two independent
sets of 8.3-compliant names (22 and 19 names) against 54,654 generated
patterns each (alphabet a, b, c, ., *, ? up to length 6; the remaining
1,333 of the 55,987 generated patterns per set are refused by the .NET
enumeration API itself for ending in ".." and are not part of either
product's -Filter semantics), with zero differences in both sets.
Tests (Tests\ItemCmdlets.Tests.ps1, "Get-ChildItem2" > "Recursion, type
filters, and depth"):
- Changed the dot-rules table (pins the new values for "Report.*",
"Report.", "Rep*.", "*.", and an empty -Filter) and the dedicated
"*.*.*" test (now expects every item), both of which pinned the old,
changed-on-purpose behavior.
- Added three rows to the existing short-name-sensitive test, to pin
that the new matcher still reads the real name, not the short name,
for the trailing-dot and "X.*" rule families.
- Added a 36-row truth table (22 fixed 8.3-compliant names, patterns
from every family the WI calls out) with the literal result of
Windows PowerShell 5.1 as static, hand-verified data; the test runs
no Get-ChildItem of its own.
- Added -Recurse with a selective -Filter across three folder levels,
a dot -Filter with -File and -Directory, an empty -Filter, and a
-Filter on a -Path that names a file.
Docs\Cmdlets\Get-ChildItem2.md: restated the -Filter parameter
description and the matching note in NOTES with the Windows PowerShell
5.1 policy and the deliberate PowerShell 7 difference, and removed the
sentences that described the dot rules as a limitation or a mismatch
with Get-ChildItem in Windows PowerShell 5.1.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
PowerShell's parameter binder uses the conversion that 3.1 fixed for
every -SecurityDescriptor parameter, so a descriptor that Get-Acl
returns, never meant for these cmdlets, now binds where it used to be
a binding error. Two more consequences of that surfaced:
With the default module setting GetInheritedFrom ($true), Get-NTFSAccess,
Get-NTFSAudit, Get-NTFSOrphanedAccess, and Get-NTFSOrphanedAudit stopped
with the InvalidOperationException that a previous fix added for a
descriptor without an item; a cmdlet user has no parameter to avoid it.
GetFileSystemAccessRules and GetFileSystemAuditRules now treat
getInheritedFrom as false for such a descriptor instead of throwing: the
entries come back with no source, the same as an entry whose source
Windows cannot name.
The private constructor that wraps a descriptor directly marked every
section, including Audit, as read; Get-Acl never reads Audit unless
-Audit is given. This made HasAuditSection wrongly report true, so the
existing #109 check let Get-NTFSAudit go on with no audit data instead
of reporting that the descriptor has none, and let Get-NTFSInheritance
report AuditInheritanceEnabled as a real value instead of null
(unknown). The constructor now includes Audit in the sections only when
the descriptor's binary form actually carries a SACL, the same test
HasSystemAcl already uses.
Get-NTFSOwner, Get-NTFSSimpleAccess, Get-NTFSOrphanedAccess,
Get-NTFSEffectiveAccess, and Add-/Remove-NTFSAccess with such a
descriptor already worked; Set-NTFSSecurityDescriptor already reported
a clear, non-terminating error. A review finding on the earlier fix is
also addressed: two assertions read a property through reflection
instead of a plain PowerShell property access, which silently turns a
throwing getter into $null without a trace and so could not tell a
getter that throws from one that legitimately returns null.
Every existing behavior for an item that is not null is unchanged.
Public signatures are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3.1 made a FileSystemSecurity2 without an item reachable from a .NET
caller (the conversions from FileSecurity and DirectorySecurity), but
six sibling call sites still dereferenced the item without checking it
first, so a caller who converted a FileSecurity or DirectorySecurity
and then read its entries, owner, inheritance, or effective access met
a NullReferenceException instead of a usable result.
GetFileSystemAccessRules and GetFileSystemAuditRules (the
FileSystemSecurity2 overload) now give each returned entry the same
null FullName that the descriptor itself reports; asking for the
source of an inherited entry (getInheritedFrom) needs the path of the
item, so it now throws one clear InvalidOperationException instead,
naming the reason, when the descriptor has none. FileSystemOwner and
FileSystemInheritanceInfo give a null FullName (and Name) the same
way; FileSystemOwner.ToString, which must never return null, gives an
empty string instead, since there is no other representation to fall
back to. The FileSystemAccessRule2(rule, item) constructor, which
EffectiveAccess.GetEffectiveAccess uses to build its result, now
accepts a null item the same way, so effective access can be
calculated for such a descriptor and the result names no path.
Every existing behavior for an item that is not null is unchanged;
only a .NET caller that reads such a descriptor can notice the
difference, and only for the better: a usable result or a clear error
instead of an unrelated NullReferenceException. Public signatures are
unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
BaseCmdletWithPrivControl.BeginProcessing and EndProcessing read
(bool)privateData["EnablePrivileges"] without checking it first; a
setting that is not a Boolean, such as the string '$true' from a typo
in the module manifest, or a missing key, made every cmdlet derived
from the class fail with an InvalidCastException or a
NullReferenceException before anything useful was said.
Enable-Privileges had its own try/catch for the same cast that raised a
different message (a ParseException), but it was unreachable, because
BeginProcessing always failed first.
A new helper, GetEnablePrivilegesSetting, centralizes the check in the
base class: a setting that is missing or not a Boolean now stops the
cmdlet with one terminating error, id EnablePrivilegesSettingInvalid,
category InvalidData, that names the setting, says it must be $true or
$false, and names the module manifest. BeginProcessing, EndProcessing,
and Enable-Privileges all use it now; the dead try/catch of
Enable-Privileges is removed, so a mistaken setting no longer produces
two different messages depending on which cmdlet hit it first. The
valid settings $true and $false keep today's behavior.
GetInheritedFrom (used by Get-NTFSAccess and Get-NTFSAudit),
GetFileSystemModeProperty, and IdentifyHardLinks (both used by
Get-ChildItem2) read their own setting the same unchecked way and share
this weakness; they are not changed here; see the final report.
Breaking: a script that caught the old InvalidCastException,
NullReferenceException, or ParseException for a malformed
EnablePrivileges setting now needs to catch the terminating error with
id EnablePrivilegesSettingInvalid instead.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
AddFileSystemAccessRule(string, List<IdentityReference2>, ...) and
AddFileSystemAuditRule(string, List<IdentityReference2>, ...) were
iterator methods (yield return), so nothing happened until the caller
enumerated the result: called as a statement, or assigned to a variable
that the caller never reads, they changed nothing. Their siblings, the
overloads for FileSystemInfo and FileSystemSecurity2 with a list, and
the single-account overloads, already built a list and wrote at once.
Both overloads now build the list and add the entries before returning,
like their siblings; a call that is never enumerated now adds the
entries just the same. An exception that adding an entry raises changes
only in timing: it is now thrown by the call itself, not by the later
enumeration of its result. The returned collection still holds one rule
per account, in the order of the account list, for both a file path and
a folder path.
Public signatures are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Both methods built a LINQ query that filtered the explicit entries down
to the ones whose account was in the given list, but never used the
result: the loop right below removed every explicit entry of the
descriptor regardless of the list, including an empty one. The cmdlets
never pass a list, so only a .NET caller of Security2.dll that does is
affected.
A non-null list now removes only the explicit entries whose account is
one of the listed accounts (compared like the rest of the class does,
by IdentityReference2 equality of the entry's SID); null still removes
every explicit entry, and an empty list now removes none. Inherited
entries are still never touched, as before. Both the FileSystemSecurity2
overload (in-memory only, until a caller writes the descriptor) and the
FileSystemInfo overload (which also writes) are fixed, for access and
audit entries alike.
Public signatures are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Converting a FileSecurity or DirectorySecurity object to
FileSystemSecurity2 (for example `[Security2.FileSystemSecurity2]
$fileSecurity`) always threw, because the conversion ignored the
descriptor it was given and built the result from an empty path, which
AlphaFS rejects. The conversion now wraps the descriptor that was
passed: SecurityDescriptor is that same instance, IsFile reflects
whether it came from a FileSecurity or a DirectorySecurity, the round
trip back to FileSecurity/DirectorySecurity returns the same instance,
and Equals/GetHashCode keep comparing descriptors by reference.
The resulting object has no item, since it was never read from a file
or folder: FullName and Name are now null instead of throwing a
NullReferenceException, and Write() throws a clear
InvalidOperationException instead of a NullReferenceException deep in
SetSecurity. A caller can still write such an object by setting its
Item property first, or by calling Write(FileSystemInfo) or
Write(string) directly, neither of which depends on an item being set.
No cmdlet reaches this conversion; only a .NET caller of Security2.dll
that converts a FileSecurity/DirectorySecurity it built itself is
affected. Public signatures are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
#128 (the rc8 record) merged on 2026-10-21 at 05:48Z, and the tests-only
round and this Memory Bank are #129 and #130 with a green CI. On the
runner the four configurations give the counts of the local run in each
of the 29 test files, so the notes no longer say that the branch is not
pushed or that the runner has not run the tests.
Records that no plain test gap is left and that the 10 rows that need a
decision (7 MaintainerDecision, 3 would-pin) wait for the maintainer.
The status paragraph of progress.md drops the list of the merged pull
requests of 2026-10-10 that the milestones already carry, which keeps
the file within its line budget.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The CI of #129 ran the new tests on the GitHub runner (windows-2025,
run 39551726767): the four configurations gave the counts of the local
run with no failure, and each of the 29 test files has the same number
of executed and skipped cases as in the local run.
The report said that the runner had not run the tests yet; it now gives
the result and states the one thing that is still open, that the new
cases ran on Windows Server 2025 only. The Evidence CSV lists the log
and the four NUnit files of the run, whose retention on GitHub ends.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Records the result of the tests-only round in the active context, the
progress, and Decision 21: 89 It blocks, 121 cases, the suite from 1,494
to 1,615 cases per configuration with no failure, 38 of 64 parameter
sets closed, 26 with a leftover, no defect; the round is on the branch
ai/tests-round-1 and has not run on the GitHub runner.
Adds to the debugging insights the helper that waited for a child that
never started: a test-name filter with spaces broke the nested quotes of
runas, which looked like a stall under load.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Adds the report of the tests-only round of the quality gate: 89 new It
blocks that run as 121 cases per configuration, so that the suite goes
from 1,494 to 1,615 cases per configuration with no failure in Windows
PowerShell 5.1 and PowerShell 7, elevated and as a basic user.
The ParameterSets CSV has the 64 rows with the status before and after:
38 are closed (7 before), 26 have something left (16 Limit, 7
MaintainerDecision, 3 would-pin), and the report names every leftover.
The Evidence CSV lists the files outside git with size and SHA-256.
No product code, cmdlet page, or CI file changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Adds 15 It blocks (25 instances, Tests\ParameterSets.Inheritance.Tests.ps1) closing the budget
items of worklist-inheritance.md rows 1-16:
- The documented no-op / current-location behavior without -Path, pinned with Push-Location into
a dedicated sandbox folder, for Disable/Enable-NTFSAccessInheritance, Disable/Enable-
NTFSAuditInheritance, Set-NTFSInheritance, Get-NTFSOwner, Set-NTFSOwner, and
Get-NTFSSecurityDescriptor.
- The OpenError category for a path that does not exist, for Disable/Enable-NTFSAccessInheritance
and Set-NTFSInheritance.
- Owner unchanged after Disable-NTFSAccessInheritance -SecurityDescriptor protects the DACL; an
independent Get-Acl -Audit oracle for Set-NTFSInheritance; the -RemoveInheritedAuditRules /
-RemoveExplicitAuditRules switches on a -SecurityDescriptor with the owner and DACL confirmed
unchanged after the write.
- The Name property and a DACL protected without the module for Get-NTFSInheritance (-Path and
-SecurityDescriptor); Get-NTFSOwner on a descriptor read without its Owner section; the SACL
unchanged after Set-NTFSOwner changes the owner; the DACL unchanged and the -PassThru type for
Set-NTFSOwner -SecurityDescriptor.
- The by-property-name pipeline and the category/target of the -PassThru ReadSecurityError for
Set-NTFSSecurityDescriptor.
Every assertion reads state with an independent .NET oracle (Get-Acl, Get-Acl -Audit) or asserts an
ErrorId/category/target triple; none repeats an existing test. Items marked Limit, would-pin, or
lab in the worklist are out of scope and untouched.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Points the comment at Move-Item2.md's -Force and Notes sections, which
document the overwrite as a replace, instead of only describing the probe
that showed it. No test logic changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Adds pipeline/positional binding, long-path, bracket/wildcard literal-path,
drive-root, omitted-path-default, and error category/target coverage for
Copy-Item2, Get-ChildItem2, Get-Item2, Move-Item2, Remove-Item2, Test-Path2,
Get-FileHash2, and Get-DiskSpace; positional binding, FileInfo pipeline input,
and share-error category coverage for New-NTFSHardLink and Get-NTFSHardLink;
positional binding and folder LinkType/target coverage for
New-NTFSSymbolicLink; and -PassThru privilege-state coverage for
Enable-Privileges and Disable-Privileges. No product code changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Add 20 new It blocks (32 executed cases once the 13-scope -ForEach of
Add-NTFSAccess/SDSimple expands) to ParameterSets.Access.Tests.ps1, closing
every REMAINING item that worklist-access.md marks budget for rows 1-13:
- Add-NTFSAccess: several accounts and positional binding (PathComplex); a
Deny entry's exact rights with no auto-added Synchronize (PathComplex and
PathSimple); a denied write and a Deny entry without rights through
PathSimple; all 13 -AppliesTo scopes of a security descriptor read back
with .NET, piped and several (SDSimple); piped and several descriptors
asserted for Add itself, not only as a fixture (SDComplex).
- Remove-NTFSAccess: the -PassThru output's count against the complete
survivor list for several piped paths; several accounts and positional
binding (PathComplex); a Deny entry's rights-reduction without
-RemoveSpecific; a missing and a denied path, piped, several (PathSimple);
rights-reduction without -RemoveSpecific and disk independence until
Set-NTFSSecurityDescriptor, piped and several descriptors (SDSimple); the
on-disk write-through only after Set-NTFSSecurityDescriptor, piped and
several descriptors (SDComplex).
- Get-NTFSAccess: what the cmdlet returns without -Path, asserted on an
actual emitted object's type (Path).
- Get-NTFSOrphanedAccess: the category of ReadSecurityError after a failed
ownership retry (Path); -ExcludeInherited and an entry added to a
descriptor only in memory (SD).
- Get-NTFSSimpleAccess: the category and target of a missing path's
ReadError (Path).
- Get-NTFSEffectiveAccess: one call combining a failing and a succeeding
path (Path).
Items the REASON marks MaintainerDecision, Limit, or would-pin are left
untouched, per the group notes of the brief. No product code changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Closes the eight remaining 'budget' parameter-set gaps that
Quality-Gate-Unknowns-2026-10-10-ParameterSets.csv lists for the audit
cmdlets, in Tests\ParameterSets.Audit.Tests.ps1 only:
- Add-NTFSAudit PathComplex: binds -Account (several accounts) and
-AuditFlags from a single piped object's property names in one call.
- Remove-NTFSAudit PathComplex: removes for several accounts named in one
call, and leaves the empty Audit SDDL and the DACL unchanged for an item
that has no SACL.
- Remove-NTFSAudit SDSimple and SDComplex: proves the item on disk keeps
its audit section until Set-NTFSSecurityDescriptor writes the change,
and that -PassThru returns FileSystemAuditRule2 objects for both sets.
- Clear-NTFSAudit Path: asserts the cleared state of the succeeding path
that follows a missing one in the same pipeline.
- Get-NTFSAudit SD: asserts the output's type, account, rights, flags, and
inherited state directly, independent of the Path set's output.
- Get-NTFSOrphanedAudit Path: adds the OpenError category of the
ReadSecurityError without the Security privilege (PermissionDenied needs
a remote/lab target and is not in scope), and -ExcludeExplicit.
- Get-NTFSOrphanedAudit SD: adds -Account and -ExcludeInherited/
-ExcludeExplicit filters against a piped security descriptor.
Every new test reads state back with an independent oracle (Get-Acl
-Audit or the .NET SACL-only accessor), and the Set-NTFSSecurityDescriptor
cases confirm the SD cmdlets change the item only in memory. The owner
retry after access denied (Limit) and the open maintainer item on
exceptions from the SD change itself (MaintainerDecision) are left out, as
the worklist directs.
9 new It blocks (10 executed cases; one is split SDSimple/SDComplex by
-ForEach) were verified test-first: a mutated copy with one flipped
expectation per new It failed only those 10 cases in the configurations
where they run, and nothing else; three repeated runs of the real file in
all four configurations (Windows PowerShell 5.1 and PowerShell 7, elevated
and basic user) gave identical, all-green results; and
Invoke-ScriptAnalyzer reports nothing, matching the base commit's file.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
rc8 is published (tag c719197, Gallery 2026-10-20 10:40:58Z) and accepted: the
identity check, three matrix cells 1,374/0/12, the suite in 24 runs, the first
lab 245/0/1 per edition, every end state CLEAN. The Memory Bank now says so in
the active context, the progress log, Decision 21, and the deployment notes
(with the published hashes, the chain script that ran the acceptance in 68
minutes, and the lesson that the saved lab machines restore cleanly in two
waves). The tech context points to where the helpers live, because TEMP was
cleaned once, and says that the list of published versions ends at rc7. The
debugging insights get the pattern of a swallowed initialization error, its
seam-free trigger (a computer name of 32,718 characters), and the warning that
came before the error.
The older state paragraphs of the active context shrink to make room.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The published rc8 passed the identity check (tag, CI run, Gallery hash, GitHub
zip), the three cells of the operating-system matrix (1,374 passed, 0 failed,
12 skipped, every end state CLEAN), the module's own suite on six machine
classes (24 runs, 0 failed, the same skipped tests as the host), and the first
lab with case 9 (245 passed, 0 failed, 1 skipped per edition, CLEAN). The counts
of the live controller equal those of the published rc7, and the live tests and
the controller are the same Git blobs, so the cells measure the changed module.
The record also shows that the boundary of the new GetEffectiveAccessError, a
computer name of 32,718 characters, holds on Windows Server 2019, 2022, and
2025 and on Windows 11 26H1, which backs the wording of the CHANGELOG and the
cmdlet page.
The four tables follow the record of the published rc7. The README names the
record and says that saved machines are restored first, the domain controllers
before the others.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The cmdlet page and the CHANGELOG said that Get-NTFSEffectiveAccess warns
that the result is based on this computer only when it returns a result. With
-ExcludeNoneAccessEntries, the cmdlet warns for an account without access and
returns nothing for it, so the text now says when it calculated a result. The
help file is regenerated with platyPS 0.14.2 and differs by that paragraph.
The tests of the documentation, the help, the wiki, the release, and the
manifest pass in Windows PowerShell 5.1 and PowerShell 7, as an administrator
and as a basic user.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Set the prerelease label to rc8 and add 5.0.0-rc7, which the PowerShell
Gallery has had since 2026-10-10, to the versions that the Gallery has
(Docs/Contributing/05-Releasing.md).
A separate commit, so that it can be dropped if the changes of this branch
go into another prerelease instead.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-NTFSHardLink and New-NTFSHardLink -PassThru combine the root of the path
that the caller gives with names that Windows reports relative to the root of
the real volume. When the two roots differ, such as for a drive that subst
made, Get-NTFSHardLink writes a FileNotFound error for a file that exists, and
New-NTFSHardLink -PassThru creates the link and then stops with a terminating
FileNotFoundException, so the links that follow in the pipeline aren't
created. The real path, and New-NTFSHardLink without -PassThru, work.
A fix needs the real volume root of the file and a decision about the names
that a mount point returns, which changes the output of two cmdlets. The cmdlet
pages and the CHANGELOG state the limit instead. A volume that is mounted into
a folder, and a junction or symbolic link to another volume, were not run and
are called probable.
Checked in Windows PowerShell 5.1 and PowerShell 7 with a substituted drive:
the five claims of the pages hold in both editions. The help file is
regenerated with platyPS 0.14.2 and differs by the two new paragraphs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-NTFSEffectiveAccess returned no access and no error when Windows refused
to start the authorization manager for the computer of -ServerName.
Win32.GetEffectiveAccess ignored what the initialization threw (an outer
catch { }), so the result looked like an account without any rights. It
reproduces on Windows Server 2025 in both editions with a name of 32,718
characters or more, which fails with error 14, where a shorter name gets RPC
server unavailable and falls back to this computer.
One try/catch now records every exception, and the cmdlet writes a
GetEffectiveAccessError. The warning that the result is based on this computer
comes only with a result now: it also preceded an error, such as for an
account that Windows can't resolve when the computer can't be reached, which
the cmdlet page and the lab tests contradict.
Two tests failed first in Windows PowerShell 5.1 and PowerShell 7, as an
administrator and as a basic user, and pass in all four configurations. The
cmdlet page, the help file, and the CHANGELOG say what changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
After the merge of #125 and #124, the maintainer decided on 2026-10-19:
- Decision 21, "Closing the gate": rc8 is mandatory (master is ahead of rc7 by
the seven product files of #125, and stable is accepted through the last
prerelease); rc8 carries the fix of the false "no access" of
Get-NTFSEffectiveAccess, while the hard-link names under a root that is not
the volume root stay a known limit listed in the release notes; the plain
test gaps are closed in a tests-only round until 2026-11-02; the steps from
rc8 to the stable tag.
- Decision 22 accepted: all ten behavior changes of rc7, two of them breaking.
- Decision 23: option 3, a decision date of 2026-11-02; the gate for #34 stays
open, and no risk is accepted.
- Decision 24 accepted: the operating-system matrix as it is.
The decision index, the active context, and the progress file follow. The
oldest entries of the progress file are shortened to stay under the line
budget.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>