daswombat1993
Goto Top

Powershell HTML Report - Anzeige von Tabellen nebeneinander

Liebe Administratoren,

ich habe ein PowerShell Script welches einige für mich relevante Daten extrahiert und in ein HTML Formular mit CSS Style Elementen umwandelt -
funktioniert auch alles wie gewünscht.

Das einzige was ich nicht hinbekomme ist die Ausgabe der Tabellen im nebeneinander.
Diese werden untereinander präsentiert und nicht wie am Screenshot nebeneinander.

Ich habe aktuell keine Lösungsansätze, alles was ich getestet habe hat nicht funktioniert.

Vielleicht hat dafür jemand von euch eine Lösung, ich komme hier nicht mehr weiter.

Das PowerShell Script (ConvertTo-Html Part ganz unten):

#Credentials==============================================================================================================================#

#Read-host -assecurestring | convertfrom-securestring | out-file C:\Users\USER\Desktop\Folder\cred.txt
$password = get-content C:\Users\USER\Desktop\Folder\cred.txt | convertto-securestring
$credential = new-object -typename System.Management.Automation.PSCredential -argumentlist "LIETZ\USER",$pass  

#Functions to extract data================================================================================================================#

function Get-Systemstatus {
          
    [CmdletBinding()]
    [OutputType([Array])] 
    param
    (
        [Parameter(Position=0, Mandatory = $true, HelpMessage="Provide server names", ValueFromPipeline = $true)]  
        $Server
    )
 
    $SystemArray = @()
 
        $Server = $Server.trim()
        $Object = '' | Select ServerName, BootUpTime, UpTime, "Physical RAM", "C: Free Space", "Memory Usage", "CPU usage"  
                         
        $Object.ServerName = $Server
 
        # Get OS details using WMI query
        $os = Get-WmiObject win32_operatingsystem -ComputerName $Server -ErrorAction SilentlyContinue | Select-Object LastBootUpTime,LocalDateTime
                         
        If($os)
        {
            # Get bootup time and local date time  
            $LastBootUpTime = [Management.ManagementDateTimeConverter]::ToDateTime(($os).LastBootUpTime)
            $LocalDateTime = [Management.ManagementDateTimeConverter]::ToDateTime(($os).LocalDateTime)
 
            # Calculate uptime - this is automatically a timespan
            $up = $LocalDateTime - $LastBootUpTime
            $uptime = "$($up.Days) days, $($up.Hours)h, $($up.Minutes)mins"  
 
            $Object.BootUpTime = $LastBootUpTime
            $Object.UpTime = $uptime
        }
        Else
        {
            $Object.BootUpTime = "(null)"  
                $Object.UpTime = "(null)"  
        }
 
        # Checking RAM, memory and cpu usage and C: drive free space
        $PhysicalRAM = (Get-WMIObject -class Win32_PhysicalMemory -ComputerName $server | Measure-Object -Property capacity -Sum | % {[Math]::Round(($_.sum / 1GB),2)})
                         
        If($PhysicalRAM)
        {
            $PhysicalRAM = ("$PhysicalRAM" + " GB")  
            $Object."Physical RAM"= $PhysicalRAM  
        }
        Else
        {
            $Object.UpTime = "(null)"  
        }
    
        $Mem = (Get-WmiObject -Class win32_operatingsystem -ComputerName $Server  | Select-Object @{Name = "MemoryUsage"; Expression = { “{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize)}}).MemoryUsage  
                        
        If($Mem)
        {
            $Mem = ("$Mem" + " %")  
            $Object."Memory Usage"= $Mem  
        }
        Else
        {
            $Object."Memory Usage" = "(null)"  
        }
 
        $Cpu =  (Get-WmiObject win32_processor -ComputerName $Server  |  Measure-Object -property LoadPercentage -Average | Select Average).Average 
                         
        If($PhysicalRAM)
        {
            $Cpu = ("$Cpu" + " %")  
            $Object."CPU usage"= $Cpu  
        }
        Else
        {
            $Object."CPU Usage" = "(null)"  
        }
 
        $FreeSpace =  (Get-WmiObject win32_logicaldisk -ComputerName $Server -ErrorAction SilentlyContinue  | Where-Object {$_.deviceID -eq "C:"} | select @{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}).freespace   
                         
        If($FreeSpace)
        {
            $FreeSpace = ("$FreeSpace" + " GB")  
            $Object."C: Free Space"= $FreeSpace  
        }
        Else
        {
            $Object."C: Free Space" = "(null)"  
        }
 
        $SystemArray += $Object
  
        $SystemArray
} 
function Get-DCDiag {
          
    [CmdletBinding()]
    [OutputType([Array])] 
    param
    (
        [Parameter(Position=0, Mandatory = $true, HelpMessage="Provide server names", ValueFromPipeline = $true)]  
        $Computername
    )
    $DCDiagArray = @()
 
            # DCDIAG ===========================================================================================
            $Dcdiag = (Dcdiag.exe /s:$Computername) -split ('[\r\n]')  
            $Results = New-Object Object
            $Results | Add-Member -Type NoteProperty -Name "ServerName" -Value $Computername  
            $Dcdiag | %{ 
            Switch -RegEx ($_) 
            { 
                "Starting test"      { $TestName   = ($_ -Replace ".*Starting test: ").Trim() }   
                "passed test|failed test" { If ($_ -Match "passed test") {    
                $TestStatus = "Passed"   
                # $TestName 
                # $_ 
                }  
                Else 
                {  
                $TestStatus = "Failed"   
                # $TestName 
                # $_ 
                } 
                } 
            } 
            If ($TestName -ne $Null -And $TestStatus -ne $Null) 
            { 
                $Results | Add-Member -Name $("$TestName".Trim()) -Value $TestStatus -Type NoteProperty -force  
                $TestName = $Null; $TestStatus = $Null
            } 
            } 
            $DCDiagArray += $Results
 
    $DCDiagArray
             
}
function Get-ADServices {
          
    [CmdletBinding()]
    [OutputType([Array])] 
    param
    (
        [Parameter(Position=0, Mandatory = $true, HelpMessage="Provide server names", ValueFromPipeline = $true)]  
        $Computername
    )
 
    $ServiceNames = "HealthService","NTDS","NetLogon","DFSR"  
    $ErrorActionPreference = "SilentlyContinue"  
    $report = @()
 
        $Services = Get-Service -ComputerName $Computername -Name  $ServiceNames
 
        If(!$Services)
        {
            Write-Warning "Something went wrong"  
        }
        Else
        {
            # Adding properties to object
            $Object = New-Object PSCustomObject
            $Object | Add-Member -Type NoteProperty -Name "ServerName" -Value $Computername  
 
            foreach($item in $Services)
            {
                $Name = $item.Name
                $Object | Add-Member -Type NoteProperty -Name "$Name" -Value $item.Status   
            }
             
            $report += $object
        }
     
    $report
}
function Get-VMReplica {
Invoke-Command -ComputerName SERVER -credential $credential -ScriptBlock `
{Get-VMReplication | Select-Object Name, State, Health, Mode, FrequencySec, PrimaryServer, ReplicaServer, ReplicaPort | `
ConvertTo-Html -Title "Report VM-Replica SERVER" -PreContent "<h1>Report VM-Replica SERVER</h1>"}  
 
Invoke-Command -ComputerName SERVER -credential $credential -ScriptBlock `
{Get-VMReplication | Select-Object Name, State, Health, Mode, FrequencySec, PrimaryServer, ReplicaServer, ReplicaPort | `
ConvertTo-Html -Title "Report VM-Replica SERVER -PreContent "<h1>Report VM-Replica SERVER</h1>"}  
}

#Set variables and create HTML Report======================================================================================================#

$systemstatus = Get-Systemstatus -Server SERVER | ConvertTo-HTML -Title "Report Systemstatus" -PreContent "<h1>Report Systemstatus</h1>"   
$dcdiag = Get-DCDiag -Computername SERVER | ConvertTo-HTML -as List -Title "Report DC-Diag" -PreContent "<h1>Report DC-Diag</h1>"  
$adservices = Get-ADServices -Computername SERVER | ConvertTo-HTML -Title "Report AD-Services" -PreContent "<h1>Report AD-Services</h1>"  
$vmreplica = Get-VMReplica

 
ConvertTo-Html -Body "$systemstatus $dcdiag $adservices $vmreplica" -CSSUri `  
"C:\Users\USER\Desktop\Folder\HtmlReport.css" |`  
Set-Content "C:\Users\USER\Desktop\Folder\HtmlReport.html"  



CSS Code:

h2
{
Border: 2px solid black;
border-collapse: collapse;
padding: 15px;
text-align: left;
Font-Family: Tahoma;
Font-Size: 16pt;
Background-Color: #81DAF5;
width: 330px;
}
h1
{ 
Font-Family: Tahoma;
Font-Size: 22pt;
}
table
{
Margin: 0px 0px 0px 4px;
Border: 2px solid black;
border-collapse: collapse;
text-align: left;
Font-Family: Tahoma;
Font-Size: 16pt;
}
th
{
Margin: 0px 0px 0px 4px;
Border: 2px solid black;
border-collapse: collapse;
padding: 15px;
text-align: left;
Font-Family: Tahoma;
Font-Size: 16pt;
Background-Color: #81DAF5;
}
td
{
Margin: 0px 0px 0px 4px;
Border: 2px solid black;
border-collapse: collapse;
padding: 15px;
text-align: left;
Font-Family: Tahoma;
Font-Size: 16pt;
Background-Color: #F2F2F2;
}
2019-04-16 11_50_11-mremoteng - confcons.xml - svwydc01

Content-ID: 441156

Url: https://administrator.de/contentid/441156

Ausgedruckt am: 08.11.2024 um 18:11 Uhr

139374
139374 16.04.2019 aktualisiert um 12:57:31 Uhr
Goto Top
Pack die Tabellen am einfachsten in DIVs und lass diese via CSS und float:left nebeneinander floaten oder nutze ein CSS-Grid. Simple HTML und CSS Grundlagen mehr brauchst du dazu nicht.

<style type="text/css">  
 .myblock {
        float:left;
        margin:0 5px;
  }
</style>

<div class="myblock">  
    <table>
    </table>
</div>
<div class="myblock">  
    <table>
    </table>
</div>
DasWombat1993
DasWombat1993 16.04.2019 um 13:35:16 Uhr
Goto Top
Danke! Soweit hatte ich auch schon gedacht / gelesen.
Nur wie ich das in der PowerShell Implementiere ist mir noch ein Rätsel.

Wie kann ich meine fertige Tabelle, welche ich aus der Funktion erhalte, in dem div angeben bzw. bei "ConvertTo-Html" festlegen das die Tabelle so formatiert wird?

Ein Codebeispiel in der wäre toll, komm da irgendwie nicht dahinter.
139374
Lösung 139374 16.04.2019 um 13:44:23 Uhr
Goto Top
Wie kann ich meine fertige Tabelle, welche ich aus der Funktion erhalte, in dem div angeben bzw. bei "ConvertTo-Html" festlegen das die Tabelle so formatiert wird?
Na selbst zusammenbauen, den Output von ConvertTo-HTML in einen String packen indem du es so formatierst wie ich oben.

$final = @"  
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
<title>HTML Document</title>
</head>
<style type="text/css">  
 .myblock {
        float:left;
        margin:0 5px;
  }
</style>
<body>
<div class="myblock">  
$($object1 | ConvertTo-HTML -Fragment | out-string )
</div>
<div class="myblock">  
$($object2 | ConvertTo-HTML -Fragment | out-string )
</div>
</body>
</html>
"@  
DasWombat1993
DasWombat1993 16.04.2019 um 13:50:11 Uhr
Goto Top
Genau sowas hab ich gesucht.

Ich werde testen, ob ich mein Problem damit lösen kann.

Feedback folgt, vorerst Danke!
DasWombat1993
DasWombat1993 16.04.2019 um 15:14:26 Uhr
Goto Top
Danke! Mein Problem ist damit gelöst (Screenshot)

Für alle die es interessiert der fertige Code:

$dcdiag = @"  
<!DOCTYPE HTML>
<html>
<head>
<title>HTML Document</title>
</head>
<style type="text/css">  

.myblock {

        float:left;

        margin:0px 50px 0px 0px;

.myblock1 {

        float:right;

        margin:0px 0px 0px 0px;
  }
</style>
<body>
<div class="myblock">  
$(Get-DCDiag -Computername SERVER | ConvertTo-HTML -as list -Fragment -PreContent "<h1>Report DcDiag DC01</h1>" | out-string )  
</div>
<div class="myblock1">  
$(Get-DCDiag -Computername SERVER | ConvertTo-HTML -as list -Fragment -PreContent "<h1>Report DcDiag DC02</h1>" | out-string )  
</div>
</body>
</html>
"@   

Da du dich sehr gut auskennst, könntest du mir vielleicht noch erklären wie ich eine in PS mit "Format-List" Formatierten Liste ein <th> hinzufüge bzw. die erste Reihe des der Tabele mit eigener Font und background color versehen kann.

PowerShell formatiert eine Liste so:

<div class="myblock">  
<h1>Report DcDiag DC01</h1>
<table>
<tr><td>ServerName:</td><td>SERVER</td></tr>
<tr><td>Connectivity:</td><td>Passed</td></tr>

Aussehen sollte es für mich aber so:

#<div class="myblock">  
<h1>Report DcDiag DC01</h1>
<table>
<tr><th>ServerName:</th><th>SERVER</th></tr>
<tr><td>Connectivity:</td><td>Passed</td></tr>#

Es würde auch reichen diese Zeile einzeln in CSS ansprechen zu können:

#<tr><td>ServerName:</td><td>SERVER</td></tr>#
2019-04-16 14_58_53-mremoteng - confcons.xml - svwydc01
139374
Lösung 139374 16.04.2019 aktualisiert um 16:43:38 Uhr
Goto Top
Mit folgendem Handwerkszeug bzw. Methodik kannst du alles so ausgeben wie du willst.
# Properties des Objects extrahieren
$listmembers = $listobj | gm -Membertype Noteproperty | Select -Expand Name
# und das Object als Tabelle formatieren
$listAsTable = @"  
<table>
   <tr> $($listmembers | %{"<th>$_</th>"}) </tr>  
    $(
        foreach($itm in $listobj){
              "<tr>"  
             $listmembers | %{"<td>" + $itm.$_ + "</td>"}  
              "</tr>"  
        }
      )
</table>
"@  

Alternativ um per CSS die erste Zeile einer Tabelle anzusprechen nimmst du den PseudoSelektor :first-child

https://developer.mozilla.org/de/docs/Web/CSS/:first-child

table tr:first-child {......}
Tschö.