Skip to content

Add -any and -all operator #28106

Open
Open

Description

@walid2mi2025-dot

Summary of the new feature / enhancement

Hello,

Please add this unary operator
-any $list
-all $list

Example:

$list = $true,$false,$true
-all $list # false
-any $list # true

Proposed technical implementation details (optional)

No response

Activity

  1. added
    Issue-Enhancementthe issue is more of a feature request than a bug
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    on Sep 25, 2026
  2. x5i4k4 commented on Sep 25, 2026

    @x5i4k4

    Any/All-Object cmdlet should be better to apply to pipeline.
    But powershell currently might not be able to implement it properly becaue early breka of process block always skips end block so the result of Any/All-Object won't be able received by next pipe(not sure if it's possible when written in C#), see: #27389

    $any = 1,2,3 | Any-Object { $_ -gt 1 }
    $any -eq $null # true
  3. rhubarb-geek-nz commented on Sep 25, 2026

    @rhubarb-geek-nz

    It can be done directly with Linq

    #!/usr/bin/env pwsh
    
    [bool[]]$list=$true,$false,$true
    
    [System.Linq.Enumerable]::All($list,[Func[bool,bool]] { param($d); $d })
    [System.Linq.Enumerable]::Any($list,[Func[bool,bool]] { param($d); $d })
    

    results in

    False
    True
    
  4. rhubarb-geek-nz commented on Sep 25, 2026

    @rhubarb-geek-nz

    I suggest that the PowerShell way would not be a unary operator. If it was unary, the only thing it could do was lists of booleans. A more compelling PowerShell solution would be just like Linq, it would "all meet some condition" or "any meet the condition". Linq is the best way for in-memory structures, a pipeline-able cmdlet would be better for the more general PowerShell scenario, like Any-Object or All-Object. Eg do any or all of these records meet some criteria.

  5. surfingoldelephant commented on Sep 25, 2026

    @surfingoldelephant

    The existing containment operators (-contains, -in, -notcontains, -notin) already provide basic -any functionality, just with less flexibility.

    So extending them is a potential alternative to adding new operators/cmdlets. First, by implementing the following, which would enable arbitrary predicates:

    And secondly by adding a new All option (just like -split has optional arguments).

    $list = $true, $false, $true
    
    # Test if any element is the boolean true.
    # Equals() avoids implicit conversions.
    $list -contains { $true.Equals($_) } 
    # True
    
    # Test if *all* elements are the boolean true.
    $list -contains { $true.Equals($_) }, 'All' 
    # False
    
    # Using -in to test for any element that's > 1:
    { $_ -gt 1 } -in 1, 2, 3 
    # True
    
    # Using -in to test for *all* elements that are > 1:
    { $_ -gt 1 }, 'All' -in 1, 2, 3
    # False

    Adding a new option would be breaking change, but I think there's an argument it falls under bucket 3 and could therefore be acceptable. An array literal on the RHS of -contains or LHS of -in is likely to be very uncommon (though of course would need to be verified). Something like this would technically be broken:

    $OFS = '|'
    
    # RHS gets stringified to "a|b".
    'a|b', 'c|d' -contains 'a', 'b' # True

    Whereas the following will always return $false (tests for reference equality), so it's unlikely users rely on this currently:

    ('a', 'b'), ('c', 'd') -contains 'a', 'b' # False
  6. rhubarb-geek-nz commented on Sep 25, 2026

    @rhubarb-geek-nz

    Going with the boolean rule of break-the-line-and-change-the-sign

    Any is

    $list -contains $True
    

    All is

    ($list -contains $true) -and ($list -notcontains $False)
    

    The complexity of all depends on what the result of an empty list should be, or whether you won't have any empty lists

    It seems to me that contains/notcontains/notin are more in line with trying to search for characters in strings rather than the set of operations offered by Linq which have direct mappings to SQL.

  7. trackd commented on Sep 25, 2026

    @trackd
    Contributor

    While I agree it would be a nice addition it has already been tried

    #11068

  8. rhubarb-geek-nz commented on Sep 27, 2026

    @rhubarb-geek-nz

    Taking the PSGallery route and noting that Any and All are not PowerShell verbs, however Join is the verb for combining data.

    As part of rhubarb-geek-nz.Joinery I have added Join-Boolean

    PS> $list = $true,$false,$true
    PS> $list | Join-Boolean -And
    False
    PS> $list | Join-Boolean -Or
    True
    PS> Join-Boolean $list -And
    False
    PS> Join-Boolean $list -Or
    True
    

    The theory is that you can use ForEach-Object to perform a script to get a boolean result from each record and pipe those through Join-Boolean to get the collective answer.

  9. 237dmitry commented on Sep 27, 2026

    @237dmitry

    For large volumes of data, it is better to use System.Linq.Enumerable, whereas a foreach loop suffices for small ones. After all, LINQ does require some initialization time upon first use.

    As variants:

    $list1 = "a", "b", "c"                   
    $list2 = "d", "c", "e", "f", "b", "b", "b"
    
    $list1.foreach({ $all += $_ -in $list2 })
    $all -ge $list1.Count
    
    # Duration 0.001 ms
    [string[]] $list1 = "a", "b", "c"
    $list2 = "d", "c", "e", "f", "b", "b", "b"
    
    $dlg = [Func[string,bool]] { $args[0] -in $list2 }
    $all = [Linq.Enumerable]::All($list1, $dlg)
    $all
    
    # Duration 0.007 ms (The first use)
    $list1 = "a", "b", "c"                   
    $list2 = "d", "e", "f", "a"
    
    $list1.foreach({ $any += $_ -in $list2 })
    [bool] $any
    
    # 0.001 ms
    [string[]] $list1 = "a", "b", "c"                 
    $list2 = "d", "e", "f", "a"
    
    $dlg = [Func[string,bool]] { $args[0] -in $list2 }
    $any = [Linq.Enumerable]::Any($list1, $dlg)
    $any
    
    # 0.003 ms (The second use)
  10. mklement0 commented on Sep 28, 2026

    @mklement0
    Contributor

    Let me attempt a summary:

    • If the $list operand is assumed to contain [bool] instances only, as in the initial post, there'd be no need for dedicated operators, as the following will do:

      • $list -contains $true - -any functionality
      • $list -notcontains $false - -all functionality
    • If the intent is to perform to-[bool] coercion on the elements of $list:

      • ([bool[]] $list) -contains $true - -any functionality
      • ([bool[]] $list) -notcontains $false - -all functionality
    • While LINQ methods are always an option, from PowerShell (a) you can only provide all-in-memory-already input and (b) their use requires .NET-specific knowledge and techniques that are from PowerShell-idiomatic.

    Previous issues have asked for more sophisticated functionality, based on using a script block ({ ... }) to determine the "truthiness" of each input element:

  11. rhubarb-geek-nz commented on Sep 28, 2026

    @rhubarb-geek-nz

    Previous issues have asked for more sophisticated functionality, based on using a script block ({ ... }) to determine the "truthiness" of each input element

    There are many existing cmdlets that let you run script-blocks based on the input records, the missing component is the And aka All or Or aka Any at the end of the pipeline. That was the purpose of Join-Boolean. Eg

    get-AllMyStuff | ForEach-Object { does $_ meet criteria } | Join-Boolean -And
    
  12. mklement0 commented on Sep 28, 2026

    @mklement0
    Contributor

    This isn't a this-or-that scenario, it is this and that.

    • The issue at hand, as well as the conceptually related ones mentioned, are operator-focused, which means they invariably operate on all-in-memory-up-front input. The trade-off is: processing speed vs. memory consumption.

    • Streaming solutions (in a PowerShell sense) are always also called for. Thus, they should be the focus of a separate proposal, say for a script block-focused Test-Object cmdlet with -All and -Any switches.

  13. kilasuit commented on Sep 30, 2026

    @kilasuit
    Collaborator

    While I agree it would be a nice addition it has already been tried

    #11068

    Thanks for pointing this out Andree Renneus (@trackd)
    Mathias R. Jessen (@IISResetMe) do you remember why you canned that PR & it's sibling pr #11060

    To quote Bruce Payette (@bpayette)

    When we get around to supporting LINQ, these operations will be covered and it will simply be

    (2,4,6).All{$_ % s -eq 0}
    (1,2,3,4,5,6).Any{$_ -gt 5}

    I personally don't see why we can't look to add -any,-all & .All{} .Any{} - other than it's just more to support & document.

    This is not likely to get properly discussed & agreed on anytime soon.
    Just to set expectations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugNeeds-TriageThe issue is new and needs to be triaged by a work group.WG-Languageparser, language semanticsWG-NeedsReviewNeeds a review by the labeled Working Group

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions