问题描述
您需要在循环之外创建基本 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
}