Search code examples
htmlpowershellreport

Display servername only once for multiple services in html report


Below is my code which is giving service status in html file

$today=(Get-Date -format dd-MM-yyyy)
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$file_path = $ScriptDir + "\report.html"
$ReportTitle="service Status $today"
$serverlist=Get-Content -Path $ScriptDir + "\serverlist.txt"
$servicelist=Get-Content -Path $ScriptDir + "\serverlist.txt"
$Style = @"
<style>
BODY{font-family:Calibri;font-size:12pt;}
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH{border-width: 1px;padding: 5px;border-style: solid;border-color: black;color:black;background-color:#0BC68D;text-align:center;}
TD{border-width: 1px;padding: 5px;border-style: solid;border-color: black;text-align:center;}
</style>
"@

$array = @()            
foreach($server in $serverlist) { 
Foreach($service in $servicelist) {         
 $svc = Get-Service $service -ComputerName $server -ea "0"            
 $obj = New-Object psobject -Property @{  
  ServerName = $server          
  DisplayName=$svc.displayname   
  Name = $svc.name            
  Status = $svc.status
    }  
     $array += $obj                 
}   
}                   
$array | Select Computername,displayname,name,status | ConvertTo-Html -property 'ServerName','Displayname','Name','Status' -head $Style -body "<h1> $ReportTitle </h1>" | foreach {if($_ -like "*<td>Running</td>*"){$_ -replace "<tr>", "<tr bgcolor=#089437>"} elseif($_ -like "*<td>Stopped</td>*" -or "*<td>Stopping</td>*" -or "*<td>Pending</td>*" -or "*<td>Starting</td>*"){$_ -replace "<tr>", "<tr bgcolor=#C60B1C>"}  else{$_}} |out-file $file_path 

now for this the output i am getting like below in html

ServerName          Displayname                    Name             Status
WIN0333.infores.com Print Spooler                  Spooler          Running
WIN0333.infores.com Remote Procedure Call (RPC)    RpcSs            Running
WIN0333.infores.com Windows Time                   W32Time          Running
WIN0333.infores.com Windows Installer              msiserver        Stopped
WIN0444.infores.com Print Spooler                  Spooler          Running
WIN0444.infores.com Remote Procedure Call (RPC)    RpcSs            Running
WIN0111.infores.com Print Spooler                  Spooler          Running
WIN0111.infores.com Remote Procedure Call (RPC)    RpcSs            Running
WIN0111.infores.com Windows Time                   W32Time          Running
WIN0111.infores.com Windows Installer              msiserver        Stopped

The report I need is to display the servername only once like below


WIN0333.infores.com Print Spooler                  Spooler          Running
                    Remote Procedure Call (RPC)    RpcSs            Running
                    Windows Time                   W32Time          Running
                    Windows Installer              msiserver        Stopped
WIN0444.infores.com Print Spooler                  Spooler          Running
                    Remote Procedure Call (RPC)    RpcSs            Running
WIN0111.infores.com Print Spooler                  Spooler          Running
                    Remote Procedure Call (RPC)    RpcSs            Running
                    Windows Time                   W32Time          Running
                    Windows Installer              msiserver        Stopped

Please need some idea on this.


Solution

  • This is a matter of what gets passed to the ConvertTo-Html cmdlet. Each object your are passing right now has the computer name, so if you want to only display the computer name on the first record for each computer you need to separate the results out by computer, and only pass the computer name for the first record of each grouping. The simplest way to do that would be with the Group-Object cmdlet with something like this:

    $array | Select Computername,displayname,name,status | Group-Object Computername | 
        ForEach-Object {
            $_.Group[0] #Pass the first record intact
            $_.Group | Select displayname,name,status -Skip 1 #Pass all records but the first with no Computername
        } | ConvertTo-Html -property 'ServerName','Displayname','Name','Status' -head $Style -body "<h1> $ReportTitle </h1>" | foreach {if($_ -like "*<td>Running</td>*"){$_ -replace "<tr>", "<tr bgcolor=#089437>"} elseif($_ -like "*<td>Stopped</td>*" -or "*<td>Stopping</td>*" -or "*<td>Pending</td>*" -or "*<td>Starting</td>*"){$_ -replace "<tr>", "<tr bgcolor=#C60B1C>"}  else{$_}} |out-file $file_path