Highlighted
Hot Shot
Hot Shot

The joy and pain of HTML

Jump to solution

I'm trying to understand how Powershell interprets the data when ConvertTo-Html is used.  I've used the cmdlet before with simple reports for snapshots, but now I want to start converting a lot of scripts that are normally .txt files to html.  Here is the first thing I'm trying. 

$custom = '<style>

BODY{background-color:#999966;}

TABLE{border-width:1px; border-style:solid; border-color:black; border-collapse:collapse;}

TH{border-width:1px; padding:0px; border-style:solid; border-color:black;}

TD{border-width:1px; padding:0px; border-style:solid; border-color:black;}

</style>'

Get-VMHost | foreach { "$(($_ | Get-VMHostNetworkAdapter | where {$_.managementtrafficenabled -eq "true"} | select -expand IP))" + "`t"*2 + "$( $_.name)"} | ConvertTo-Html -Head $custom -Body '<H2>ESXi IP addresses</H2>' | Out-File c:\Scripts\Hosts.htm

I formatted the above script to conform to how someone would input the data into their Windows hosts file, but I want to be able to take each line, and place it into row within an HTML document.

I tried this:

$HTMLhosts = Get-VMHost | foreach { "$(($_ | Get-VMHostNetworkAdapter | where {$_.managementtrafficenabled -eq "true"} | select -expand IP))" + "`t"*2 + "$( $_.name)"}

When I look at the above variable, I see the data that I want, each line shows the IP address and the name of the host on the same line, ex;   5.5.5.5     ESXihostname

If I look at $HTMLhosts[0], I see 1 line with the IP address and the hostname.  If I use $HTMLhosts[0] | ConvertTo-html -fragment I get some random number

PS C:\Users> $HTMLhosts[0] | ConvertTo-Html -Fragment

<table>

<colgroup><col/></colgroup>

<tr><th>*</th></tr>

<tr><td>41</td></tr>

</table>

I don't know if each current object $_ needs to be converted somehow, and admittedly I'm not a whiz when it comes to html.  Of course I'm hoping for an answer so my current script can be converted to html, but overall, I want to understand how and why Powershell sees the html data and how to manipulate it.

Any help is appreciated.

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Expert
Expert

Hello, DZ1-

I'd say that the problem is to do with the way that you are mixing strings and objects.  You should have better results if you stick with objects, and then pipe those to the ConvertTo-Html cmdlet.  Something like:

$strCustomCSS = @'
<style>
BODY {background-color:#999966;}
TABLE {border-width:1px; border-style:solid; border-color:black; border-collapse:collapse;}
TH, TD {border-width:1px; padding:0px; border-style:solid; border-color:black;}
</style>
'@

Get-VMHost |
   
## select the properties to output
    Select @{n="IP"; e={(Get-VMHostNetworkAdapter -VMHost $_ | where {$_.ManagementTrafficEnabled -eq $true}).IP}}, Name |
   
## convert the objects to HTML, using the CSS
    ConvertTo-Html -Head $strCustomCSS -Body '<H2>ESXi IP addresses</H2>' | Out-File c:\Scripts\Hosts.htm -Encoding Ascii

That work out for you?

View solution in original post

0 Kudos
5 Replies
Highlighted
Hot Shot
Hot Shot

I see that the number is the actual length of the object, but of course, I don't know why that's the output. 

<table>

<colgroup><col/></colgroup>

<tr><th>*</th></tr>

<tr><td>41</td></tr>

</table>

I really want the IP address to come first, and then the hostname, maybe I'll play around with the formatting. 

0 Kudos
Highlighted
Expert
Expert

Hello, DZ1-

I'd say that the problem is to do with the way that you are mixing strings and objects.  You should have better results if you stick with objects, and then pipe those to the ConvertTo-Html cmdlet.  Something like:

$strCustomCSS = @'
<style>
BODY {background-color:#999966;}
TABLE {border-width:1px; border-style:solid; border-color:black; border-collapse:collapse;}
TH, TD {border-width:1px; padding:0px; border-style:solid; border-color:black;}
</style>
'@

Get-VMHost |
   
## select the properties to output
    Select @{n="IP"; e={(Get-VMHostNetworkAdapter -VMHost $_ | where {$_.ManagementTrafficEnabled -eq $true}).IP}}, Name |
   
## convert the objects to HTML, using the CSS
    ConvertTo-Html -Head $strCustomCSS -Body '<H2>ESXi IP addresses</H2>' | Out-File c:\Scripts\Hosts.htm -Encoding Ascii

That work out for you?

View solution in original post

0 Kudos
Highlighted
Hot Shot
Hot Shot

Thanks, that worked perfectly.  The downside, and this is just me...I don't know why I didn't think to use Select-Object with the hash table.  I'm banging my head over here, I never thought to try it.  If you know, because I tried the foreach statement again and I didn't use any subexpressions, and it still came out with the length of the text, I really want to know why that happens.  In either case, thanks again, and I need to remember to keep trying other ways of retrieving data.  Last one....thanks.

0 Kudos
Highlighted
Expert
Expert

Hello-

Good, glad to hear it.  Well, now you'll be sure to try it that way next time, right?  Good.

As for, "why that happens":  ConvertTo-Html makes the HTML representation of the objects passed to it, displaying a column for each property of object.  There is a bit more involved if the objects coming in do not all have the same properties, but that does not come in to play in your example.

So, you were making a string object in your example.  If you have a look at the members of a String, you will see that there is but one member of type "property":  the Length property.  So, ConvertTo-Html makes the HTML representation of the String object by making a column for the values of the string's Length property.  Effectively, that was like running:

"my favorite string" | ConvertTo-Html -Property Length

If you are in a situation in the future where you do only have a string (instead of some rich objects with all of the properties that hold the data that you crave), and you want to use ConvertTo-Html, a useful feature is that you can use a calculated property for the value of the -Property parameter.  For example:

"some string here`t`tserverName.dom.com" | ConvertTo-Html -Property @{l="myString"; e={$_.ToString()}}, Length

While PowerShell is good at string manipulation, that is not from where the power comes -- objects are good; we like objects.  Keep using those objects, and keep being happy.  And, yes, you are welcome.  Enjoy.

0 Kudos
Highlighted
Hot Shot
Hot Shot


Thanks again for your help, I'll make sure to take your advice next time.  

0 Kudos