Private/Html.ps1

#Requires -Version 5.1

function Get-SMBeatReportStrings {
    param(
        [ValidateSet('de', 'en')]
        [string]$Language
    )

    if ($Language -eq 'de') {
        return @{
            Title            = 'SMBeat - SMB-Nutzungsbericht'
            Period           = 'Zeitraum'
            Coverage         = 'Abdeckung'
            Totals           = 'Gesamt (Sent = abgerufen)'
            Sent             = 'Sent (GiB)'
            Received         = 'Received (GiB)'
            Read             = 'Read (GiB)'
            Write            = 'Write (GiB)'
            NicIn            = 'NIC In (GiB)'
            NicOut           = 'NIC Out (GiB)'
            ByServer         = 'Je Server'
            ByShare          = 'Top Shares'
            ByClient         = 'Top Clients (Richtwert)'
            ByUser           = 'Top Benutzer (Richtwert)'
            Hourly           = 'Stundenverlauf'
            Daily            = 'Tagesverlauf'
            Weekly           = 'Wochenverlauf'
            Previous         = 'Vorperiode gleicher Laenge'
            Warnings         = 'Hinweise'
            Name             = 'Name'
            Foot             = 'Sent-Bytes sind SMB-Daten vom Server zum Client (abgerufen). Read-Bytes sind Share-/Plattenlesen und koennen bei Cache-Treffern kleiner sein. Share/Server-Totals sind belastbar; Client/User sind Richtwerte (Session-Zaehler enden mit der Sitzung). NIC-Werte enthalten allen Traffic inkl. Protokoll-Overhead. _Total und IPC$ sind ausgeblendet.'
            Company          = 'Merlin Kommunikationstechnik'
            NoData           = 'Keine Samples im gewaehlten Zeitraum.'
        }
    }

    return @{
        Title            = 'SMBeat - SMB usage report'
        Period           = 'Period'
        Coverage         = 'Coverage'
        Totals           = 'Totals (Sent = retrieved)'
        Sent             = 'Sent (GiB)'
        Received         = 'Received (GiB)'
        Read             = 'Read (GiB)'
        Write            = 'Write (GiB)'
        NicIn            = 'NIC In (GiB)'
        NicOut           = 'NIC Out (GiB)'
        ByServer         = 'By server'
        ByShare          = 'Top shares'
        ByClient         = 'Top clients (approximate)'
        ByUser           = 'Top users (approximate)'
        Hourly           = 'Hourly'
        Daily            = 'Daily'
        Weekly           = 'Weekly'
        Previous         = 'Previous period of equal length'
        Warnings         = 'Notes'
        Name             = 'Name'
        Foot             = 'Sent bytes are SMB data from server to client (retrieved). Read bytes are share/disk reads and can be smaller on cache hits. Share/server totals are authoritative; client/user figures are approximate (session counters vanish when the session ends). NIC values include all traffic plus protocol overhead. _Total and IPC$ are excluded.'
        Company          = 'Merlin Kommunikationstechnik'
        NoData           = 'No samples in the selected window.'
    }
}

function ConvertTo-SMBeatHtmlEncode {
    param(
        [string]$Text
    )

    if ($null -eq $Text) {
        return ''
    }

    [System.Net.WebUtility]::HtmlEncode($Text)
}

function ConvertTo-SMBeatHtmlTable {
    param(
        [object[]]$Rows,
        [string]$NameHeader,
        [string]$SentHeader,
        [string]$WriteHeader,
        [int]$Top = 15
    )

    if ($null -eq $Rows -or $Rows.Count -eq 0) {
        return '<p class="muted">-</p>'
    }

    $sb = New-Object System.Text.StringBuilder
    [void]$sb.AppendLine('<table><thead><tr>')
    [void]$sb.AppendLine(('<th>{0}</th><th>{1}</th><th>{2}</th>' -f `
        (ConvertTo-SMBeatHtmlEncode -Text $NameHeader), `
        (ConvertTo-SMBeatHtmlEncode -Text $SentHeader), `
        (ConvertTo-SMBeatHtmlEncode -Text $WriteHeader)))
    [void]$sb.AppendLine('</tr></thead><tbody>')
    $i = 0
    foreach ($row in $Rows) {
        if ($i -ge $Top) { break }
        $i++
        [void]$sb.AppendLine(('<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>' -f `
            (ConvertTo-SMBeatHtmlEncode -Text ([string]$row.Name)), `
            $row.SentGiB, `
            $row.WriteGiB))
    }
    [void]$sb.AppendLine('</tbody></table>')
    $sb.ToString()
}

function ConvertTo-SMBeatHtmlSeries {
    param(
        [object[]]$Rows,
        [string]$SentHeader,
        [string]$WriteHeader
    )

    if ($null -eq $Rows -or $Rows.Count -eq 0) {
        return '<p class="muted">-</p>'
    }

    $sb = New-Object System.Text.StringBuilder
    [void]$sb.AppendLine(('<table><thead><tr><th>Start</th><th>{0}</th><th>{1}</th></tr></thead><tbody>' -f `
        (ConvertTo-SMBeatHtmlEncode -Text $SentHeader), `
        (ConvertTo-SMBeatHtmlEncode -Text $WriteHeader)))
    foreach ($row in $Rows) {
        [void]$sb.AppendLine(('<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>' -f `
            (ConvertTo-SMBeatHtmlEncode -Text ([string]$row.PeriodStart)), `
            $row.SentGiB, `
            $row.WriteGiB))
    }
    [void]$sb.AppendLine('</tbody></table>')
    $sb.ToString()
}

function ConvertTo-SMBeatHtmlReport {
    param(
        [Parameter(Mandatory = $true)]
        $Report,
        [ValidateSet('de', 'en')]
        [string]$Language
    )

    $t = Get-SMBeatReportStrings -Language $Language
    $start = $Report.StartUtc.ToString('u', $script:SMBeatInvariant)
    $end = $Report.EndUtc.ToString('u', $script:SMBeatInvariant)
    $warnHtml = ''
    if ($Report.Warnings -and $Report.Warnings.Count -gt 0) {
        $items = ($Report.Warnings | ForEach-Object { '<li>' + (ConvertTo-SMBeatHtmlEncode -Text $_) + '</li>' }) -join ''
        $warnHtml = '<section><h2>{0}</h2><ul>{1}</ul></section>' -f (ConvertTo-SMBeatHtmlEncode -Text $t.Warnings), $items
    }

    $prevHtml = ''
    if ($Report.PreviousTotals) {
        $p = $Report.PreviousTotals
        $prevHtml = @'
<section>
  <h2>{0}</h2>
  <table><tbody>
    <tr><th>{1}</th><td>{2}</td></tr>
    <tr><th>{3}</th><td>{4}</td></tr>
  </tbody></table>
</section>
'@
 -f (ConvertTo-SMBeatHtmlEncode -Text $t.Previous), (ConvertTo-SMBeatHtmlEncode -Text $t.Sent), $p.SentGiB, (ConvertTo-SMBeatHtmlEncode -Text $t.Write), $p.WriteGiB
    }

    $totals = $Report.Totals

    @"
<!DOCTYPE html>
<html lang="$Language">
<head>
  <meta charset="utf-8" />
  <title>$($t.Title)</title>
  <style>
    body { font-family: Segoe UI, Helvetica, Arial, sans-serif; margin: 2rem; color: #1a1a1a; }
    h1 { font-size: 1.4rem; }
    h2 { font-size: 1.1rem; margin-top: 1.6rem; }
    table { border-collapse: collapse; margin: 0.5rem 0 1rem; }
    th, td { border: 1px solid #ccc; padding: 0.35rem 0.6rem; text-align: left; }
    th { background: #f3f3f3; }
    .muted { color: #666; }
    footer { margin-top: 2rem; font-size: 0.85rem; color: #555; max-width: 50rem; }
  </style>
</head>
<body>
  <h1>$(ConvertTo-SMBeatHtmlEncode -Text $t.Title)</h1>
  <p>$(ConvertTo-SMBeatHtmlEncode -Text $t.Company)</p>
  <p><strong>$(ConvertTo-SMBeatHtmlEncode -Text $t.Period):</strong> $start - $end ($($Report.TimeZone))<br />
     <strong>$(ConvertTo-SMBeatHtmlEncode -Text $t.Coverage):</strong> $($Report.CoveragePct)%</p>
  $warnHtml
  <section>
    <h2>$(ConvertTo-SMBeatHtmlEncode -Text $t.Totals)</h2>
    <table><tbody>
      <tr><th>$(ConvertTo-SMBeatHtmlEncode -Text $t.Sent)</th><td>$($totals.SentGiB)</td></tr>
      <tr><th>$(ConvertTo-SMBeatHtmlEncode -Text $t.Received)</th><td>$($totals.ReceivedGiB)</td></tr>
      <tr><th>$(ConvertTo-SMBeatHtmlEncode -Text $t.Read)</th><td>$($totals.ReadGiB)</td></tr>
      <tr><th>$(ConvertTo-SMBeatHtmlEncode -Text $t.Write)</th><td>$($totals.WriteGiB)</td></tr>
      <tr><th>$(ConvertTo-SMBeatHtmlEncode -Text $t.NicIn)</th><td>$($totals.NicInGiB)</td></tr>
      <tr><th>$(ConvertTo-SMBeatHtmlEncode -Text $t.NicOut)</th><td>$($totals.NicOutGiB)</td></tr>
    </tbody></table>
  </section>
  $prevHtml
  <section>
    <h2>$(ConvertTo-SMBeatHtmlEncode -Text $t.ByServer)</h2>
    $(ConvertTo-SMBeatHtmlTable -Rows $Report.ByServer -NameHeader $t.Name -SentHeader $t.Sent -WriteHeader $t.Write)
  </section>
  <section>
    <h2>$(ConvertTo-SMBeatHtmlEncode -Text $t.ByShare)</h2>
    $(ConvertTo-SMBeatHtmlTable -Rows $Report.ByShare -NameHeader $t.Name -SentHeader $t.Sent -WriteHeader $t.Write)
  </section>
  <section>
    <h2>$(ConvertTo-SMBeatHtmlEncode -Text $t.ByClient)</h2>
    $(ConvertTo-SMBeatHtmlTable -Rows $Report.ByClient -NameHeader $t.Name -SentHeader $t.Sent -WriteHeader $t.Write)
  </section>
  <section>
    <h2>$(ConvertTo-SMBeatHtmlEncode -Text $t.ByUser)</h2>
    $(ConvertTo-SMBeatHtmlTable -Rows $Report.ByUser -NameHeader $t.Name -SentHeader $t.Sent -WriteHeader $t.Write)
  </section>
  <section>
    <h2>$(ConvertTo-SMBeatHtmlEncode -Text $t.Hourly)</h2>
    $(ConvertTo-SMBeatHtmlSeries -Rows $Report.Hourly -SentHeader $t.Sent -WriteHeader $t.Write)
  </section>
  <section>
    <h2>$(ConvertTo-SMBeatHtmlEncode -Text $t.Daily)</h2>
    $(ConvertTo-SMBeatHtmlSeries -Rows $Report.Daily -SentHeader $t.Sent -WriteHeader $t.Write)
  </section>
  <section>
    <h2>$(ConvertTo-SMBeatHtmlEncode -Text $t.Weekly)</h2>
    $(ConvertTo-SMBeatHtmlSeries -Rows $Report.Weekly -SentHeader $t.Sent -WriteHeader $t.Write)
  </section>
  <footer>$(ConvertTo-SMBeatHtmlEncode -Text $t.Foot)</footer>
</body>
</html>
"@

}