问题
I am using Get-ChildItem to fetch locally installed certs. Then I'd like to delete these certs from my local certificate store. If I execute the script below it will work when there is more than one item returned in both the Get-ChildItem queries. But if only one item is returned in either of the queries the addition of the two collections will fail. Simply because with only one object returned the implementation only returns one instance and not a collection of one. What is the right approach here? I won't know if the result(s) returned from my queries will result in 0, 1 or multiple certs.
$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()
}
回答1:
If $myCerts
might just be a single item, use the array subexpression operator @( )
:
$allCerts = @($myCerts) + $trustedPeopleCerts
回答2:
Another solution that accomplishes the same thing is to use a unary comma operator to ensure that $myCerts
is always an array. Consider the following examples that we are using for one element and 0 elements.
$myCerts = Get-Item C:\temp
$myCerts.GetType().FullName
$myCerts = $null
$myCerts.GetType().FullName
The above would generate System.IO.DirectoryInfo
and an error for "call[ing] a method on a null-valued expression"
Now lets try the same thing with unary comma operator.
$myCerts = ,(Get-Item C:\temp)
$myCerts = ,($null)
The answer in both cases is System.Object[]
I forgot about one thing this is doing. @()
might be preferential in this case as it is an array sub expression. The comma operator I think here is creating a multidimentional array. When used in a pipe it is unrolled and you still get the data you are looking for but it is an important difference to note.
回答3:
I found a way to do it using a pipeline in case arrays aren't playing nicely. This will write each item to the local pipeline inside the ScriptBlock
, which gets captured to the variable.
$merged = & {
$foo
$bar
}
来源:https://stackoverflow.com/questions/30801868/how-do-i-merge-two-lists-in-powershell-when-one-list-might-be-just-one-item-fr