当一个列表可能只是 Get-Item 中的一项时,如何在 PowerShell 中合并两个 "lists"?

How do I merge two "lists" in PowerShell when one list might be just one item from Get-Item?

我正在使用 Get-ChildItem 获取本地安装的证书。然后我想从我的本地证书存储中删除这些证书。如果我执行下面的脚本,当在两个 Get-ChildItem 查询中返回多个项目时,它将起作用。但是,如果在任一查询中仅返回一个项目,则两个集合的添加将失败。仅仅是因为只有一个对象返回实现只有 returns 个实例而不是一个实例的集合。这里正确的方法是什么?我不知道我的查询返回的结果是否会产生 0 个、1 个或多个证书。

$myCerts = Get-ChildItem cert:\CurrentUser\My | Where-Object { $_.Subject -like "CN=$certName" }
$trustedPeopleCerts = Get-ChildItem cert:\CurrentUser\TrustedPeople | Where-Object { $_.Subject -like "CN=$certName" }

$allCerts = $myCerts + $trustedPeopleCerts

foreach ($cert in $allCerts) {
    $store = Get-Item $cert.PSParentPath
    $store.Open('ReadWrite')
    $store.Remove($cert)
    $store.Close()
}

如果 $myCerts 可能只是单个项目,请使用数组子表达式运算符 @( ):

$allCerts = @($myCerts) + $trustedPeopleCerts

另一种实现相同目的的解决方案是使用 unary comma operator 来确保 $myCerts 始终是一个数组。考虑以下我们用于 1 个元素和 0 个元素的示例。

$myCerts = Get-Item C:\temp
$myCerts.GetType().FullName

$myCerts = $null
$myCerts.GetType().FullName

以上将生成 System.IO.DirectoryInfo 和 "call[ing] a method on a null-valued expression"

的错误

现在让我们用一元逗号运算符尝试同样的事情。

$myCerts = ,(Get-Item C:\temp)
$myCerts = ,($null)

两种情况的答案都是System.Object[]

我忘记了它正在做的一件事。 @() 在这种情况下可能是优先的,因为它是一个数组子表达式。我认为这里的逗号运算符正在创建一个多维数组。当在管道中使用时,它会展开,您仍然可以获得您正在寻找的数据,但这是一个需要注意的重要区别。

我找到了一种使用管道来完成此操作的方法,以防数组无法很好地播放。这会将每个项目写入 ScriptBlock 内的本地管道,并捕获到变量。

$merged = & {
    $foo
    $bar
}