Robert Westerlund's helpful answer shows one way of filtering out $null
and ''
(empty-string) values, using the Where-Object
cmdlet, which coerces the output from the script block to a Boolean, causing both $null
and ''
evaluate to $False
and thus causing them to be filtered out.
This answer shows an alternative approach and discusses other aspects of the question.
tl;dr:
@{
data = @((Get-ChildItem -Recurse Cert:\LocalMachine).FriendlyName) -notlike '' |
Sort-Object | Select-Object @{ n='{#CERTINFO}'; e={ $_ } }
} | ConvertTo-Json
Using -ne $Null
i get boolean results like true or false...
You only get a Boolean if the LHS is a scalar rather than an array - in the case of an array, the matching array elements are returned.
To ensure that the LHS (or any expression or command output) is an array, wrap it in @(...)
the array-subexpression operator (the following uses PSv3+ syntax ):
@((Get-ChildItem -Recurse Cert:\LocalMachine).FriendlyName) -notlike ''
Note the use of -notlike ''
to weed out both $null
and ''
values: -notlike
forces the LHS to a string, and $null
is converted to ''
.
By contrast, if you wanted to use -ne $null
, you'd have to use -ne ''
too so as to also eliminate empty strings (though, in this particular case you could get away with just -ne ''
, because ConvertTo-Json
would simply ignore $null
values in its input).
Calling .FriendlyName
on the typically array-valued output of Get-ChildItem
directly is a PSv3+ feature called member-access enumeration: the .FriendlyName
property access is applied to each element of the array, and the results are returned as a new array.
Filtering and sorting the values before constructing the wrapper objects with the {#CERTINFO}
property not only simplifies the command, but is also more efficient.
Further thoughts:
Do not use Write-Host
to output data: Write-Host
bypasses PowerShell's (success) output stream; instead, use Write-Output
, which you rarely need to call explicitly however, because its use is implied.
- Instead of
write-host "{"
, use write-output "{"
or - preferably - simply "{"
by itself.
PowerShell supports multi-line strings (see Get-Help about_Quoting_Rules
), so there's no need to output the result line by line:
@"
{
"data":
$(<your ConvertTo-Json pipeline>)
}
"@
However, given that you're invoking ConvertTo-Json
anyway, it's simpler to provide the data
wrapper as a PowerShell object (in the simplest form as a hashtable) to ConvertTo-Json
, as shown above.