ConvertTo-HTML类

时间:2016-08-08 09:53:51

标签: html5 powershell powershell-v4.0

我有一组简单的PowerShell函数可以检索系统统计信息,将它们转换为HTML片段&然后将它们全部加入到一个大的HTML文件中。

我遇到了某些特定功能的问题,而其他人似乎工作得很好,尽管我使用完全相同的原则。

这将检索系统信息:

function Get-ApplicationLogs {
    $query = '<QueryList>
              <Query Id="0" Path="Application">
              <Select Path="Application">*[System[(Level=1  or Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]</Select>
              </Query>
              </QueryList>'

    $logs = Get-WinEvent -ComputerName $ComputerName -ErrorAction SilentlyContinue -FilterXml $query | Sort-Object {$_.Id}

    foreach ($log in $logs) {
        $props = [ordered]@{'Id'=$log.Id;
                  'Error Type'=$log.LevelDisplayName;
                  'Provider Name'=$log.ProviderName;
                  'Timestamp'=$log.TimeCreated;
                  'Message'=$log.Message;
                 }

        $obj = New-Object -TypeName PSObject -Property $props

        Write-Output $obj   
    }
}

这将逻辑应用于函数并对输出HTML代码的类应用条件格式: -

$applogs = Get-ApplicationLogs -computername $computername  | 
           Select -Property *,@{
               name='class';e={
                   if ($_.'Error Type' -match 'Error' -or 'Critical') {
                       '<td class="danger">'
                   } elseif ($_.'Error Type' -match 'Warning') {
                       '<td class="warning">'
                   } else {
                       '<td>'
                   }
               }
           }

将它们绑定在一起并执行td类标记替换:

$frag8 = $applogs | Select 'ID','Error Type','Provider Name','Timestamp','Message' | 
         ConvertTo-Html -As Table -Fragment -PreContent '<hr>', '<h3>Application Logs</h3>' |
         foreach { $_ -replace '<td>',$($applogs.class) } |
         Out-String

但由于某些原因,我得到一个非常偏斜的HTML输出,它似乎生成的标签多于每个值所需的标签: -

<hr>
<h3>Application Logs</h3>
<table>
<colgroup><col/><col/><col/><col/><col/></colgroup>
<tr><th>Id</th><th>Error Type</th><th>Provider Name</th><th>Timestamp</th><th>Message</th></tr>
<tr>
<td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger">10021</td>
<td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger">Warning</td>
<td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger">Windows Server Update Services</td>
<td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger">08/08/2016 04:37:42</td>
<td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger"> <td class="danger">The catalog was last synchronized successfully 1 or more days ago.</td>
</tr>

1 个答案:

答案 0 :(得分:0)

foreach { $_ -replace '<td>',$($applogs.class) }

以上语句将使用<td>所有记录的class值替换每个 $applogs元素,从而将如果<td>包含多条记录,则为$applogs个元素。

在您尝试添加格式设置信息时,您不再拥有原始对象,因此您需要解析信息以使您的格式基于您创建的HTML字符串。当我回答你original question时,我已经告诉过你了。解决方案也(基本上)保持不变。

$re = '<tr><td>.*?</td><td>(Error|Warning)</td>'

... | ForEach-Object {
  if ($_ -match $re) {
    $type = $matches[1]
    $_ -replace '<td>', "<td class='$type'>"
  } else {
    $_
  }
} | ...

此外,正如comments to your question中提到的@wOxxOm,逻辑操作$_.'Error Type' -match 'Error' -or 'Critical'无法正常工作。表达式的评估如下:

$_.'Error Type' -match 'Error' -or 'Critical'
($_.'Error Type' -match 'Error') -or ('Critical')
($_.'Error Type' -match 'Error') -or ($true)
$true

因为PowerShell中的non-empty strings evaluate to $true,如果至少有一个操作数为$true,则boolean OR operation的结果为$true

如果您想继续使用-match运算符,可以在正则表达式中使用替换:

$_.'Error Type' -match 'Error|Critical'

您还可以进行两次单独的-eq比较:

$_.'Error Type' -eq 'Error' -or $_.'Error Type' -eq 'Critical'

或检查Error Type值是否包含在有效值数组中:

'Error', 'Critical' -contains $_.'Error Type'