HTML Reports in PowerShell eBook Question

Hi Guys,

First, thanks to Don Jones for the HTML Reports in PowerShell eBook. I’ve just started my journey with PowerShell and this is one of my first reads. Actually, I’ve also watched most of Don’s videos on Youtube so I’d really like to say thanks to Don for everything he is doing for the PowerShell community.

I am using the template from the attached eBook to try to generate the first report. I want to use the OS Caption rather than the OSBuild. When I substitute OSBuild for Caption then move Caption to be the first element in the hashtable the report displays the Caption as the second element. I do not see anyway to specify the order in which the elements are displayed.

function Get-InfoOS {
    $os = Get-WmiObject -class Win32_OperatingSystem -ComputerName $ComputerName
    $props = @{ 'Caption'=$os.caption;
    New-Object -TypeName PSObject -Property $props

if ($everything_ok) {
       $filepath = Join-Path -Path $Path -ChildPath "$computer.html"
       $html_os = Get-InfoOS -ComputerName $computer |
                            ConvertTo-HTML -As List -Fragment -PreContent "OS" |


Hash tables don’t preserve order. However, if you specify properties when converting to HTML, it’ll preserve that order. Newer versions of PowerShell also let you declare the hash table as ordered, which is a bit less memory efficient sometimes.

A few demonstrations of how to specify the order of properties in an object. The object is piped to Out-Host at each step of the way, to demonstrate that they all produce the same order of properties in the table:

# PowerShell 2.0 compatible:

    # Create an object, then pipe it to Select-Object with the property order you want:

    $props = @{
        Caption = 'My Caption'
        OSVersion = 'My OS Version'
        SPVersion = 'My SP Version'

    $object = New-Object psobject -Property $props | 
              Select-Object -Property 'Caption', 'OSVersion', 'SPVersion'
    $object | Out-Host

    # Use Select-Object to create the object in the first place, cutting New-Object out entirely:

    $props = @(
        @{ Name = 'Caption'; Expression = { 'My Caption' } }
        @{ Name = 'OSVersion'; Expression = { 'My OS Version' } }
        @{ Name = 'SPVersion'; Expression = { 'My SP Version' } }

    $object = "" | Select-Object -Property $props
    $object | Out-Host

    # Create an empty object and use Add-Member to build its properties in order.  PowerShell 1.0 compatible,
    # but much slower than other options

    $object = New-Object psobject
    Add-Member -InputObject $object -MemberType NoteProperty -Name Caption -Value 'My Caption'
    Add-Member -InputObject $object -MemberType NoteProperty -Name OSVersion -Value 'My OS Version'
    Add-Member -InputObject $object -MemberType NoteProperty -Name SPVersion -Value 'My SP Version'

    $object | Out-Host

# Techniques that only work in PowerShell 3.0 or later
    # Use the [pscustomobject] literal syntax

    $object = [pscustomobject] @{
        Caption = 'My Caption'
        OSVersion = 'My OS Version'
        SPVersion = 'My SP Version'

    $object | Out-Host

    # Use the [ordered] literal syntax, then convert to an object later.  This
    # has the advantage of letting you build the hash table dynamically, while
    # still preserving the order.

    $props = [ordered] @{
        Caption = 'My Caption'

    $props['OSVersion'] = 'My OS Version'
    $props['SPVersion'] = 'My SP Version'

    # You can convert hashtables to psobjects either by casting to [pscustomobject] or calling New-Object.
    # (Casting is faster, if performance is a concern.)
    $object = [pscustomobject]$props
    $object | Out-Host

    $object = New-Object psobject -Property $props
    $object | Out-Host

Thanks Dave, I’ll check it out.

Thanks for the feedback.

OK, I’m still learning how to reply on this board :slight_smile: