1

I'm out of luck finding information...

This powershell script collecting cert info in LocalMachine:

$cert_days = get-childitem cert:LocalMAchine -recurse  |
select  @{Name="{#CERTINFO}"; Expression={($_.FriendlyName)}} |
Sort "{#CERTINFO}"

write-host "{"
write-host " `"data`":`n"

convertto-json $cert_days 

write-host
write-host "}"

I can't exclude Nulls or empty items like " ".

Using -ne $Null i get boolean results like true or false...

I would appreciate to hear Yours advice how to eliminate nulls or empty entries

Richlv
  • 3,954
  • 1
  • 17
  • 21
  • 1
    You have a slightly problematic property name with ```{#CertInfo}```, but I'm assuming you really want that name. Otherwise, if you don't feel strongly about the ```{#CertInfo}``` property name, your code would probably be easier to write and read if you change the ```Select``` to ```Select FriendlyName``` or similar, instead. – Robert Westerlund Dec 09 '17 at 14:38
  • I need #CERTINFO for Zabbix Low Level Discovery rules : ) – Laurentijus Golovenko Dec 09 '17 at 14:48

2 Answers2

1

To exclude empty entries, you could add a filter to remove those, preferably before the Sort-Object call., e.g.

$certs = ls Cert:\LocalMachine\ -Recurse |
    Select @{Name = '{#CertInfo}'; Expression = {$_.FriendlyName}} |
    Where { $_.'{#CertInfo}' } |
    Sort '{#CertInfo}'
Robert Westerlund
  • 4,750
  • 1
  • 20
  • 32
0

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.

mklement0
  • 382,024
  • 64
  • 607
  • 775