Windows 服务状态报告

Windows 服务状态报告

我编写了一个脚本来检查处于挂起状态的 Windows 服务,并根据主题行向用户发送一封电子邮件。

  • 我想发送包含图像或表格数据的电子邮件,该数据由服务器名称、服务名称、服务启动类型和服务状态组成,但现在我只能发送包含正文的电子邮件。

我如何以以下格式的表格形式发送包含服务器名称、服务名称、服务启动类型和服务状态的数据的电子邮件?在此处输入图片描述

#AUTHOR: Chandrakanth Reddy
#DATE: 8/15/2021

#Email Details
$FromAddress = 'XYZ.com'
$ToAddress = 'XYZ.com'
$SmtpServer = 'ABC.com'

#Machine to be monitored
$Computer = "XXXX"

#Create a subset of the previous array for services you want to monitor
$ServiceName = "WSearch"

Foreach ($ServerName in $Computer) {
  Foreach ($Service in $ServiceName) {
    #Get current status
      $CurrentStatus = Get-Service -Name $ServiceName -ComputerName $Computer #| Where-Object { $_.Status -eq "StartPending" }

      if ($_.Status -eq "StartPending") {
        #$CurrentStatus = 'StartPending'

        If (($FromAddress) -And ($SmtpServer)) {
          $msgBody = $ServiceName + " " + "Windows Service is" + " " + $CurrentStatus +" " + "on" + " " + $Computer
          Send-MailMessage -from $FromAddress -to $FromAddress -SmtpServer $SmtpServer -Subject "$Computer - $ServiceName Windows Service is in Hung state '$CurrentStatus' " -BodyAsHtml $msgBody
        }
      }
      elseif ($_.Status -eq "StopPending") {
        #$CurrentStatus = 'StopPending'

        If (($FromAddress) -And ($SmtpServer)) {
          $msgBody = $ServiceName + " " + "Windows Service is" + " " + $CurrentStatus +" " + "on" + " " + $Computer
          Send-MailMessage -from $FromAddress -to $ToAddress -SmtpServer $SmtpServer -Subject "$Computer $ServiceName is not running" -BodyAsHtml $msgBody
        }
      }
      elseif ($_.Status -eq 'Running' -or $_.Status -eq 'Stopped' -or $_.Status -eq 'ContinuePending') {
        Exit
      }
  }
}
Exit

答案1

正如评论所说,您当前的代码会发送一封电子邮件每一个列表中的服务每一个来自计算机名称数组的计算机。

我建议收集所有需要的信息作为对象并使用转换为 HTML根据该数据创建一个漂亮的 HTML 表格。

使用 Here-String 作为主体 HTML 模板,您可以设置样式来按照您想要的方式为表格着色。

-Name由于和-ComputerName参数都Get-Service可以采用名称数组,因此您的代码可以压缩如下:

$machines = 'XXX', 'YYY'           # array of computernames to check
$services = 'WSearch','SENS'       # array of services to check

$result = Get-Service -Name $services -ComputerName $machines | 
        Where-Object { $_.Status -match '(Start|Stop)pending' } |
        # output objects to be collected in $result
        Select-Object @{Name = 'Server name'; Expression = {$_.MachineName}},
                      @{Name = 'Service name'; Expression = {$_.Name}},
                      @{Name = 'Service Start Type'; Expression = {$_.StartType}},
                      @{Name = 'Service Status'; Expression = {$_.Status}}


# only send an email if there is something to alert (found services in 'StartPending' and/or 'StopPending' state)
# the @() is needed to force $result to be an array even if it has only one item
if (@($result).Count) {
    # convert the resulting array of objects into a HTML table
    $table = ($result | Sort-Object 'Server name' | ConvertTo-Html -Fragment) -join [environment]::NewLine

    # create a HTML template for the email using a Here-String
    $htmlTemplate = @"
<html><head>
<style>
    body, table {font-family: sans-serif; font-size: 10pt; color: #000000;}
    table {border: 1px solid white; border-collapse: collapse;}
    th {border: 1px solid white; background: #0000af; padding: 3px; color: #ffffff;}
    td {border: 1px solid white; padding: 3px; color: #000000;}
</style>
</head><body>
Pending services.<br />
@@TABLE@@
<br />
</body></html>
"@

    # create a Hashtable to splat the parameters to Send-MailMessage
    $mailParams = @{
        From       = '[email protected]'
        To         = '[email protected]'
        Subject    = 'Services not running {0:yyyy-MM-dd}' -f (Get-Date)
        SmtpServer = 'ABC.com'
        Body       = $htmlTemplate -replace '@@TABLE@@', $table
        BodyAsHtml = $true
    }

    # send the email
    Send-MailMessage @mailParams
}
else {
    Write-Host "No services found that were in StartPending or StopPending state. No email was sent." -ForegroundColor Green
}

如果像您所评论的那样,您想要显示 一组服务器中所有服务的所有可能的服务状态(除了两种之外ContinuePending, Paused, PausePending, Running, StartPending, Stopped, StopPending) ,那么您可以将上述内容更改为:

$machines = 'XXX', 'YYY'           # array of computernames to check
$result = Get-Service -ComputerName $machines | 
        Where-Object { $_.Status -notmatch 'Running|Stopped' } |
        # output objects to be collected in $result
        Select-Object @{Name = 'Server name'; Expression = {$_.MachineName}},
                      @{Name = 'Service name'; Expression = {$_.Name}},
                      @{Name = 'Service Start Type'; Expression = {$_.StartType}},
                      @{Name = 'Service Status'; Expression = {$_.Status}}

相关内容