Search code examples
powershellpowershell-4.0

Break lines in powershell array and then convert it to html?


I swear I've been searching a lot and still haven't found any solution to this thing. What I do is basically converting arrays to HTML but I can't find any way to break the words of the array in new lines.

For example:

$Member.ExpireOn=((Invoke-SqliteQuery -SQLiteConnection $C -Query "SELECT expireon FROM exceptions_test WHERE (identity='$User')").ExpireOn -join "`r`n")

$Member.ExpireOn is basically this:

31/01/2019 00:00:00 31/03/2019 00:00:00 31/03/2019 00:00:00

so even if I join it with -join "rn" or with <br> I can't find any way to have a line for each element in the array. I need to do it because after that I print the whole array in a HTML file and this is what I get:

enter image description here

instead of having a <br> between those words. Hopefully somebody can help me :)


Solution

  • even if I join it with -join "`r`n"

    Whitespace in HTML is insignificant, so you cannot force line breaks this way; they will show in the HTML markup (source code), but not when rendered.

    or with <br>

    The problem is that ConvertTo-Html - which I assume you're using - escapes any HTML markup in the input objects' property values (it assumes you want to use the values verbatim), so you cannot pass <br> through in order to make a single table cell use multiple line - you'll see literal <br> strings in the table, because ConvertTo-Html has escaped them as &lt;br&gt;.


    A quick and dirty workaround would be to manually convert the escaped <br> elements back to their HTML form:

    # Sample input objects
    $o = [pscustomobject] @{
      Foo = 'Cert A'
      # Join the array elements with <br>
      ExpireOn = (Get-Date), (Get-date).AddDays(1) -join '<br>'
    }, [pscustomobject] @{
      Foo = 'Cert B'
      ExpireOn = (Get-Date).AddDays(2), (Get-date).AddDays(3) -join '<br>'
    }
    
    # Convert *escaped* <br> elements back to literal '<br>'
    # NOTE: This will replace *all* instances of '&lt;br&gt;' in the 
    #       document text, wherever it may occur.
    ($o | ConvertTo-Html) -replace '&lt;br&gt;', '<br>'
    

    This yields the following, showing that the <br> was effectively passed through, which should make the input date values render on individual lines:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>HTML TABLE</title>
    </head><body>
    <table>
    <colgroup><col/><col/></colgroup>
    <tr><th>Foo</th><th>ExpireOn</th></tr>
    <!-- Note the <br> elements -->
    <tr><td>Cert A</td><td>2/5/2020 12:51:45 PM<br>2/6/2020 12:51:45 PM</td></tr>
    <tr><td>Cert B</td><td>2/7/2020 12:51:45 PM<br>2/8/2020 12:51:45 PM</td></tr>
    </table>
    </body></html>
    

    In Chrome on my Mac, this renders as follows:

    enter image description here


    If you need a more robust solution, you'll have to use an HTML parser - see this answer.