Best way to product HTML from results

Hello all. I’m doing a general inventory summary report but struggling on how to output these results all to one HTML page. I know i can do objects which might help make this easier, but is it possible to do it with the code below? I’m assuming the response will be to populate custom objects…

$Servers = Get-ADComputer -Filter {(OperatingSystem -Like "*Server*")} -Properties operatingsystem

$ProdTotal,$DevTotal,$TestTotal,$ProdCTXTotal,$TestCTXTotal,$DevCTXTotal = 0 #numerical summary
$Prod2012,$Prod2008,$Prod2003,$Prod2000,$ProdCTX2012,$ProdCTX2008,$ProdCTX2003,$ProdCTX2000 = 0 #OS Summary

foreach ($server in $servers)
{
if ($server.name -like “p" -and $Server.name -NotLike "xxxCTX”)
{$ProdTotal++
if ($server.operatingsystem -like “2012”)
{$Prod2012++}
elseif ($server.operatingsystem -like “2008”)
{$Prod2008++}
elseif ($server.operatingsystem -like “2003”)
{$Prod2003++}
elseif ($server.operatingsystem -like “2000”)
{$Prod2000++}

    }
    elseif ($server.name -like "*p" -and $Server.Name -like "xxxCTX*")
    {$ProdCTXTotal++
        if ($server.operatingsystem -like "*2012*")
        {$ProdCTX2012++}
        elseif ($server.operatingsystem -like "*2008*")
        {$ProdCTX2008++}
        elseif ($server.operatingsystem -like "*2003*")
        {$ProdCTX2003++}
        elseif ($server.operatingsystem -like "*2000*")
        {$ProdCTX2000++}
    }
    elseif ($server.name -like "*T" -and $Server.name -NotLike "xxxCTX*")
    {$TestTotal++}
    elseif ($server.name -like "*T" -and $Server.Name -like "xxxCTX*")
    {$TestCTXTotal++}
    elseif ($server.name -like "*D" -and $Server.name -NotLike "xxxCTX*")
    {$DevTotal++}
    elseif ($server.name -like "*D" -and $Server.Name -like "xxxCTX*")
    {$DevCTXTotal++}

}

Thanks!

You don’t really mention how you want the HTML formatted, but I’m guessing you want it in a table or similar. If so, I guess you need to either create the HTML manually or create custom objects and pipe it to ConvertTo-HTML.

Below is a sample on how you could do to perform this calculation and then HTML formatting.

Given the following assumptions:

*) If no servers in an environment use a specific OS version, you don’t need it in the table
*) All OS versions contain only one part of the name which is four digits next to each other and this is the relevant part for determining OS version.
*) All objects in the server list follows the “correct” naming scheme
*) You have no other requirements on the HTML formatting than that it should be a table.

And that the following test data list is representatative of your $servers list:

$servers = @(
    @{ Name = "Serv1P"; OperatingSystem = "Windows Server 2008" }
    @{ Name = "Serv2P"; OperatingSystem = "Windows Server 2012" }
    @{ Name = "Serv3P"; OperatingSystem = "Windows Server 2003" }
    @{ Name = "Serv4T"; OperatingSystem = "Windows Server 2012" }
    @{ Name = "Serv5T"; OperatingSystem = "Windows Server 2008" }
    @{ Name = "Serv6D"; OperatingSystem = "Windows Server 2000" }
    @{ Name = "Serv7D"; OperatingSystem = "Windows Server 2012" }
    @{ Name = "Serv8P"; OperatingSystem = "Windows Server 2012" }
    @{ Name = "Serv9D"; OperatingSystem = "Windows Server 2012" }
    @{ Name = "ServCTX1D"; OperatingSystem = "Windows Server 2012" }
    @{ Name = "ServCTX2T"; OperatingSystem = "Windows Server 2008" }
    @{ Name = "ServCTX3P"; OperatingSystem = "Windows Server 2012" }
    @{ Name = "ServCTX4P"; OperatingSystem = "Windows Server 2003" }
)

You should be able to do something like the following to count servers and format the HTML.

$servers | 
    #I use Foreach instead of Select since I often think it's easier to read
    #unless you are only selecting direct properties
    foreach {
        $_.operatingsystem -match "\d{4}" | Out-Null
        $os = $matches[0]
        $Environment = $_.Name[$_.Name.Length - 1]
        New-Object PSOBject -Property @{
            Name = $_.Name
            IsCtx = ($_.Name -match "CTX")
            OS = $os
            Environment = $Environment
        }
    } |
    #We can use Group-Object to do counting. It seems as though you count
    #based on environment, whether it's CTX or not and the OS year.
    Group Environment, IsCtx, OS | 
    Foreach {
        #I'm getting the group property values from the first item in the
        #group list instead of the group value array, since I feel that 
        #being able to use a property name instead of an array index makes
        #for easier to read code
        $type = "NonCTX"
        if ($_.Group[0].IsCtx){ 
            $type = "CTX"
        }
        $Environment = $_.Group[0].Environment
        switch ($Environment)
        {
            "D" { $Environment = "Dev" }
            "T" { $Environment = "Test" }
            "P" { $Environment = "Prod" }
        }
        New-Object PSObject -Property ([ordered]@{  
            Type = $type
            Environment = $Environment
            OS = $_.Group[0].OS
            Count = $_.Count
        })
    } | 
    #Just in case you want it sorted
    Sort Type, Environment, OS |
    ConvertTo-Html -Title "Server List"