通过 Powershell 将 SQL 结果附加到 HTML 表

问题描述

您需要在循环之外创建基本 html(包含标题/正文/表格标题/表格标题内容)。在循环中,您只创建表格单元格。

从那里,您构建完整的 HTML。

# Just some data... I used calculated field to have the same field name as you.
$Value = Get-Service | Select @{'Name' = 'host' ; 'Expression' = { "localhost" } },
@{'Name' = 'Service' ; 'Expression' = { $_.ServiceName } }, Status


$HtmlTemplate = @{
    Base_Date_TableLoop          = @'
<head> 
          <Meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>

          <style>
            TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
            TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
            TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}

            table.center {
            margin-left: auto; 
            margin-right: auto;
            }
          </style>

          <title>Warning</title>
          </head> 
          <body> 

          <h3>Apps are Stopped !</h3>

          <h4>Timestamp: {0:Date}</h4>

        <table>

            <tr>
                <th>sql</th>
                <th>DB</th>
                <th>Service Status</th>
            </tr>

          {0:TableLoop}

          </table>
          </body>
'@
    TableLoop_sql_DB_Status = @'
        <tr>
            <td>{0}</td>
            <td>{1}</td>
            <td>{2}</td>
        </tr>
'@
}

 $Date = Get-Date
$Table = [System.Text.StringBuilder]::new()




foreach ($mylocal in $Value ) {

    $hostname = $mylocal.host
    $Service = $mylocal.Service
    $Status = $mylocal.Status

    $Table.AppendLine(($HtmlTemplate.TableLoop_sql_DB_Status -f $hostname,$Service,$Status)) | Out-Null

}

$HtmlBody = $HtmlTemplate.Base_Date_TableLoop.Replace('{0:Date}',$Date).Replace('{0:TableLoop}',$Table.ToString())

$HtmlBody | Out-File 'SomeReport.html' 

我喜欢将我所有的 html 元素放在一个变量中。在前面的示例中,我曾经$HtmlTemplate存储所有片段。这些作品不打算直接编辑,而是作为我的构建块。

对于元素本身,我个人喜欢Base_Date_TableLoop在每个下划线划分我需要替换的内容的位置上设置一些东西,这样以后更容易进行替换,而不必考虑去哪里。

我将“{0}”与for-f循环片段和基本 html 片段混合使用。这是因为基本 html 包含用于格式运算符的括号,需要将其加倍以使运算符忽略它们。由于我不想随意修改html,所以我使用.Net方法,它可以让我替换我需要的东西,而不必完全修改html。此外,在这里使用,而不是因为后者是正则表达式运算符,我不希望那样。{0:TableLoop}``.replace``{}``-f``.replace``.Replace``-Replace

解决方法

我有来自多个 SQL Server 的多个数据库。

我正在尝试使用这些数据库/SQL Server 中的 Powershell 将 SQL 数据输出到 HTML 表,然后发送邮件。我制作的脚本有效,但它会为 html 报告中的每个结果输出多个表格。我想要的是将数据附加到同一个表(只有一个包含所有数据的表)。在如何将数据连接到只有一个表上有点挣扎。

#Set flag to 0 for email notification (if any)
$alert= 0


$List = Get-Content -Path "C:\Users\testadmin\Documents\Log\serverlist.txt"


Foreach($Server in $ServerList){

$SQL = ($Server -split '=')[0] 
$ = ($Server -split '=')[1]



$Query = "select host,Service,Status from Table with(nolock)"

$Value = Invoke-Sqlcmd -ServerInstance $SQL -Database $DB -Query $Query 




foreach($mylocal in $Value ){

    $hostname = $mylocal.host
    $Service= $mylocal.Service
    $Status = $mylocal.Status 



         if($Status -ne 'Running'){

         $alert= 1

         $Body += "<head> 
          <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>

          <style>
            TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
            TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
            TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}

            table.center {
            margin-left: auto; 
            margin-right: auto;
            }
          </style>

          <title>Warning</title>
          </head> 
          <body> 

          <h3>Apps are Stopped !</h3>

          <h4>Timestamp: $(Get-Date)</h4>

        <table>

          <tr>
            <th>SQL</th>
            <th>DB</th>
            <th>Service Status</th>
          </tr>

          <tr>
            <td>$SQL</td>
            <td>$DB</td>
            <td>$Status</td>
          </tr>

          </table>
          </body>
          " 
         } 


         else{
            Write-Host ("no alert") 
         }
  }  

}

  if($alert-eq '1'){

          $Mail = @{
            From = 'testadmin@local.com' 
            To = 'localadmin@local.com'
            Subject = 'Warning!!'
            smtpserver = 'myrelay.test.com'
            Body = $Body
            BodyAsHtml = $true
          } 


          Send-MailMessage @Mail
        }