Browse Source

feat!: match any listed attribute in Get-ChildItem2 -Attributes

Get-ChildItem2 -Attributes returned only the items that had all the listed
attributes, so -Attributes Hidden, ReadOnly returned nothing where
Get-ChildItem returns both kinds of items. It now returns the items that have
any of them (#5).

BREAKING CHANGE: to get only the items with all the listed attributes,
filter the result with Where-Object, as the cmdlet page shows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
pull/105/head
Raimund Andree 7 days ago
parent
commit
55be4d7842
  1. 5
      CHANGELOG.md
  2. 8
      Docs/Cmdlets/Get-ChildItem2.md
  3. 3
      NTFSSecurity/ItemCmdlets/GetChildItem2.cs
  4. 10
      NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
  5. 26
      Tests/ItemCmdlets.Tests.ps1

5
CHANGELOG.md

@ -49,6 +49,11 @@ The format is based on
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. To get the old result, filter with `Where-Object`,
as the cmdlet page shows
([#5](https://github.com/raandree/NTFSSecurity/issues/5))
### Deprecated

8
Docs/Cmdlets/Get-ChildItem2.md

@ -57,19 +57,19 @@ PS C:\> Get-ChildItem2 -Path C:\Data -Recurse -Depth 1 -Filter '*.log'
Returns the log files in `C:\Data` and in its immediate subfolders. Without `-Depth`, the command would descend through the entire tree.
### Example 4: List hidden system files
### Example 4: List hidden or system files
```PowerShell
PS C:\> dir2 -Path C:\Data -Attributes Hidden, System
```
Uses the `dir2` alias and returns the items of `C:\Data` that have both the hidden and the system attribute.
Uses the `dir2` alias and returns the items of `C:\Data` that have the hidden or the system attribute, like `Get-ChildItem -Attributes Hidden, System`.
## PARAMETERS
### -Attributes
Specifies a set of file attributes. The cmdlet returns only the items that have all the attributes you list; separate several values with commas, as in `-Attributes Hidden, System`. When you use this parameter, the cmdlet ignores `-Force`, `-Hidden`, `-System`, and `-ReadOnly`, and it returns matching hidden items without `-Force`.
Specifies a set of file attributes. Like `Get-ChildItem`, the cmdlet returns the items that have at least one of the attributes you list; separate several values with commas, as in `-Attributes Hidden, System`. To get only the items that have all of them, filter the result, for example with `Where-Object { ($_.Attributes -band [IO.FileAttributes]'Hidden, System') -eq [IO.FileAttributes]'Hidden, System' }`. When you use this parameter, the cmdlet ignores `-Force`, `-Hidden`, `-System`, and `-ReadOnly`, and it returns matching hidden items without `-Force`.
```yaml
Type: FileAttributes
@ -307,7 +307,7 @@ The `PrivateData` section of the module manifest `NTFSSecurity.psd1` contains tw
A folder that cannot be read produces a non-terminating error with the ID `DirUnauthorizedAccessError` for an access denial or `DirUnspecifiedError` for any other failure, and a path that does not exist produces the error `FileNotFound`. In each case the cmdlet continues with the next path. Failures that occur while `-Recurse` collects the subfolders of a folder are reported as verbose messages only, not as errors.
Before 5.0.0, a `-Path` value that points to a file stopped the cmdlet with an `InvalidCastException`.
Before 5.0.0, a `-Path` value that points to a file stopped the cmdlet with an `InvalidCastException`, and `-Attributes` returned only the items that had all the listed attributes.
## RELATED LINKS

3
NTFSSecurity/ItemCmdlets/GetChildItem2.cs

@ -275,7 +275,8 @@ namespace NTFSSecurity
if (MyInvocation.BoundParameters.ContainsKey("Attributes"))
{
if ((current.Attributes & attributes) != attributes)
// Like Get-ChildItem, an item matches when it has any of the listed attributes (#5).
if (attributes != 0 && (current.Attributes & attributes) == 0)
continue;
writeItem = true;

10
NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml

@ -3524,7 +3524,7 @@ PS C:\&gt; Disable-Privileges</dev:code>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
<maml:name>Attributes</maml:name>
<maml:description>
<maml:para>Specifies a set of file attributes. The cmdlet returns only the items that have all the attributes you list; separate several values with commas, as in `-Attributes Hidden, System`. When you use this parameter, the cmdlet ignores `-Force`, `-Hidden`, `-System`, and `-ReadOnly`, and it returns matching hidden items without `-Force`.</maml:para>
<maml:para>Specifies a set of file attributes. Like `Get-ChildItem`, the cmdlet returns the items that have at least one of the attributes you list; separate several values with commas, as in `-Attributes Hidden, System`. To get only the items that have all of them, filter the result, for example with `Where-Object { ($_.Attributes -band [IO.FileAttributes]'Hidden, System') -eq [IO.FileAttributes]'Hidden, System' }`. When you use this parameter, the cmdlet ignores `-Force`, `-Hidden`, `-System`, and `-ReadOnly`, and it returns matching hidden items without `-Force`.</maml:para>
</maml:description>
<command:parameterValueGroup>
<command:parameterValue required="false" command:variableLength="false">ReadOnly</command:parameterValue>
@ -3668,7 +3668,7 @@ PS C:\&gt; Disable-Privileges</dev:code>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
<maml:name>Attributes</maml:name>
<maml:description>
<maml:para>Specifies a set of file attributes. The cmdlet returns only the items that have all the attributes you list; separate several values with commas, as in `-Attributes Hidden, System`. When you use this parameter, the cmdlet ignores `-Force`, `-Hidden`, `-System`, and `-ReadOnly`, and it returns matching hidden items without `-Force`.</maml:para>
<maml:para>Specifies a set of file attributes. Like `Get-ChildItem`, the cmdlet returns the items that have at least one of the attributes you list; separate several values with commas, as in `-Attributes Hidden, System`. To get only the items that have all of them, filter the result, for example with `Where-Object { ($_.Attributes -band [IO.FileAttributes]'Hidden, System') -eq [IO.FileAttributes]'Hidden, System' }`. When you use this parameter, the cmdlet ignores `-Force`, `-Hidden`, `-System`, and `-ReadOnly`, and it returns matching hidden items without `-Force`.</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">FileAttributes</command:parameterValue>
<dev:type>
@ -3857,7 +3857,7 @@ PS C:\&gt; Disable-Privileges</dev:code>
<maml:para>The default table view shows the `Mode`, `Inherits`, `LastWriteTime`, `Size(M)`, and `Name` columns. `Inherits` is `False` for an item whose access inheritance is disabled. Reading that value costs one access to the ACL of each displayed item, which slows down the display of large listings; to avoid it, select the properties you need, for example with `Format-Table -Property Mode, LastWriteTime, Length, Name`. Objects that you pipe to another command are not affected. Before 5.0.0, the column showed `True` for every item.</maml:para>
<maml:para>The `PrivateData` section of the module manifest `NTFSSecurity.psd1` contains two settings that this cmdlet reads when it starts. `GetFileSystemModeProperty` adds the calculated `Mode` property to every item. `IdentifyHardLinks` adds the `HardLinkCount` property to every file, which requires an extra call into the file system for each file and therefore slows down large listings noticeably. Set either value to `$false` in the manifest and import the module again if you prefer the faster enumeration over the additional properties.</maml:para>
<maml:para>A folder that cannot be read produces a non-terminating error with the ID `DirUnauthorizedAccessError` for an access denial or `DirUnspecifiedError` for any other failure, and a path that does not exist produces the error `FileNotFound`. In each case the cmdlet continues with the next path. Failures that occur while `-Recurse` collects the subfolders of a folder are reported as verbose messages only, not as errors.</maml:para>
<maml:para>Before 5.0.0, a `-Path` value that points to a file stopped the cmdlet with an `InvalidCastException`.</maml:para>
<maml:para>Before 5.0.0, a `-Path` value that points to a file stopped the cmdlet with an `InvalidCastException`, and `-Attributes` returned only the items that had all the listed attributes.</maml:para>
</maml:alert>
</maml:alertSet>
<command:examples>
@ -3883,10 +3883,10 @@ PS C:\&gt; Disable-Privileges</dev:code>
</dev:remarks>
</command:example>
<command:example>
<maml:title>------------- Example 4: List hidden system files -------------</maml:title>
<maml:title>------------ Example 4: List hidden or system files ------------</maml:title>
<dev:code>PS C:\&gt; dir2 -Path C:\Data -Attributes Hidden, System</dev:code>
<dev:remarks>
<maml:para>Uses the `dir2` alias and returns the items of `C:\Data` that have both the hidden and the system attribute.</maml:para>
<maml:para>Uses the `dir2` alias and returns the items of `C:\Data` that have the hidden or the system attribute, like `Get-ChildItem -Attributes Hidden, System`.</maml:para>
</dev:remarks>
</command:example>
</command:examples>

26
Tests/ItemCmdlets.Tests.ps1

@ -78,6 +78,32 @@ Describe 'Get-ChildItem2' {
($lines | Where-Object -FilterScript { $_ -match 'Inheriting\.txt\s*$' }) | Should -Match '\bTrue\b'
}
}
Context 'With -Attributes' {
BeforeAll {
$attributeFolder = New-TestSandboxItem -Sandbox $sandbox -Name 'Attributes' -Directory
$hiddenFile = Join-Path -Path $attributeFolder -ChildPath 'Hidden.txt'
$readOnlyFile = Join-Path -Path $attributeFolder -ChildPath 'ReadOnly.txt'
$plainFile = Join-Path -Path $attributeFolder -ChildPath 'Plain.txt'
Assert-TestSandboxPath -Sandbox $sandbox -Path $hiddenFile, $readOnlyFile, $plainFile
Set-Content -LiteralPath $hiddenFile, $readOnlyFile, $plainFile -Value 'Attributes'
(Get-Item -LiteralPath $hiddenFile -Force).Attributes = [IO.FileAttributes]::Hidden
(Get-Item -LiteralPath $readOnlyFile).Attributes = [IO.FileAttributes]::ReadOnly
}
# Before 5.0.0, the cmdlet returned only the items that had all the listed attributes (#5).
It 'Should return the items that have any of the listed attributes, like Get-ChildItem' {
$result = @(Get-ChildItem2 -Path $attributeFolder -Attributes Hidden, ReadOnly)
@($result.Name | Sort-Object) | Should -Be @('Hidden.txt', 'ReadOnly.txt')
}
It 'Should return only the items with the attribute when one is listed' {
$result = @(Get-ChildItem2 -Path $attributeFolder -Attributes ReadOnly)
$result.Name | Should -Be 'ReadOnly.txt'
}
}
}
Describe 'Copy-Item2, Move-Item2, and Remove-Item2 with several paths' {

Loading…
Cancel
Save