对于 C#/Java 程序员,相当于“.Single()”的 Powershell

Gro*_*tav 5 linq powershell

我正在为我的 CI 编写一些脚本,我注意到我在断言过滤器的唯一性方面做得不好。例如,一个脚本假设

$availableZip = $(Get-ChildItem -Path .\ -Filter "*SomeName*.zip" -Recurse).FullName
Run Code Online (Sandbox Code Playgroud)

将提供一个唯一的条目,但它可能不提供任何条目,也可能提供多个条目。

这当然可以通过一些 If-Else 检查在下游处理,但我想做的是优雅地推动 PowerShell 为我生成一个错误,例如

$availableZip = $(Get-ChildItem -Path .\ -Filter "*SomeName*.zip" -Recurse | Where -Single).FullName
Run Code Online (Sandbox Code Playgroud)

这样Where -Single会抛出某种SetIsEmptyExceptionor SetContainsMultipleElementsException,所有 PowerShell 装备都专门指向这一行,甚至可能包括重复的成员。

Where-Object : value 包含多个元素,其中只允许一个,可用元素: firstDirectory\SomeSoftware.zip, Another-SomeSoftware.zip at C:\Users\geoff\Code\Project\MyScript.ps1:33 char:73
+ 。 ..ChildItem -Path .\ -Filter " SomeSoftware .zip" -recurse | Where -Single).FullName
+ ~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], SingletonSetContainsMultipleElementsException
+fullyQualifiedErrorId : TooManyElements,Microsoft.PowerShell.Commands.WhereObjectCommand

有没有内置的方法可以让我做到这一点?是否有一些我可以使用的 PowerShell 技巧,或者我应该使用一个带有私有函数的小模块(如果是这样,最优雅的实现是什么?)

Jac*_*vin 2

如果你想 A. 使用 Pipeline,B. 有一些可重用的东西,C. 有一些相当快的东西:

  function Where-SingleObject {
    param (
      [Parameter(Mandatory, ValueFromPipeline, HelpMessage='Data to process')]$InputObject
    )
    begin {
      $i = 0
    }
    process {
      if($i -eq 1) {
        throw "Error"
      }; $i++
    }
    end {
      return $InputObject
    }

  }

  (Get-ChildItem -Path '' -Filter '' -Recurse).FullName | Where-SingleObject
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以删除Mandatory并添加 0 的自定义错误。