![自动服务未启动时的电子邮件通知(Windows Server 2012 R2)](https://linux22.com/image/668797/%E8%87%AA%E5%8A%A8%E6%9C%8D%E5%8A%A1%E6%9C%AA%E5%90%AF%E5%8A%A8%E6%97%B6%E7%9A%84%E7%94%B5%E5%AD%90%E9%82%AE%E4%BB%B6%E9%80%9A%E7%9F%A5%EF%BC%88Windows%20Server%202012%20R2%EF%BC%89.png)
我们的环境中有几台服务器(Windows Server 2012 R2),它们会自动安装更新并然后重新启动。
重启后,我们想检查所有设置为自动启动的 (Windows) 服务的状态。如果某个服务未启动,脚本将尝试启动该服务 3 次,如果所有尝试都失败,它将发送电子邮件通知,以便我们检查此服务器上该服务的问题所在。
我想知道是否已经存在一个简单的解决方案,也许是 PowerShell 脚本?
答案1
我建议您考虑购买 NMS。我们使用 PRTG,它运行良好。在其中,您可以创建使用 WMI 监控 Windows 服务的传感器。您可以配置传感器以在服务中断时发送邮件/启动脚本。
PRTG 是通过传感器授权的,但免费版本为您提供 100 个传感器,这对于几台服务器来说应该足够了(每个服务需要一个传感器来监控)
答案2
Powershell 是监控这些服务的绝佳方式。奇怪的是,我今天刚刚读到一篇关于此内容的博客。如果我能找到该脚本,我会尝试链接它,但它的大致要点是:
1.) 找到设置为自动启动的服务。
2.)检查服务状态。
诀窍在于
get-service
cmdlet 不会输出任何类型的“StartupType”,因此您必须使用 Win32_Service WMI 对象。
Foreach($Server in $ServerList){
Get-WmiObject -ComputerName $Server Win32_Service |
Where-Object {$_.StartMode -eq 'Auto' -AND $_.State -eq 'Stopped'}
}
这将为您提供一份符合您所需参数的服务列表。
笔记 对此有几点需要注意:
1.) 我强烈建议您在服务器启动几分钟后启动此脚本,因为 $_.StartMode -eq 'Auto' 将包含设置为在启动后立即启动的服务和设置为在延迟后自动启动的服务。
2.) 这条命令返回的服务可能不是您关心的监控。(例如,在我的笔记本电脑上,名为“TrustedInstaller”的服务符合此条件,并作为已停止的服务返回 :/ )因此,您很可能也需要过滤掉这些服务。
答案3
答案4
我找到了一个非常适合我的 Powershell 脚本,我只需要稍微定制一下。这是链接http://doitcloudy.blogspot.de/2014/07/scriptgesteuerter-neustart-von-windows.html(德语,但页面底部的脚本全部是英语)。但是,我需要一些关于这部分的帮助(第 130 行及以下):
foreach ($item in $report){
Write-Host "Starting Service " $item.Name " on server: " $item.Server -Foregroundcolor yellow
$start = Get-Date
$startSVCblock = {param($item) Start-Service -InputObject (Get-Service -ComputerName $item.Server -Name $item.Name)}
$j = Start-Job -ScriptBlock $startSVCblock -Arg $item
do {
if ($j.State -ne 'Running') { break}
$j | Receive-Job
} while (((Get-Date) - $start) -le $timeout)
}
我看到这是脚本启动服务的部分,但我不习惯在 Powershell 中执行作业。我应该如何编辑脚本,以便在启动服务失败时将服务名称写入日志文件?也许使用 try/catch?
编辑:
如果有人偶然发现这个问题并想知道我是如何解决的:经过大量研究,我发现将 Receive-Job 的输出写入日志文件极其困难。所以我选择了一种不同的方法:我在作业完成后检查服务器是否正在运行。以下是代码:
foreach ($item in $report){
Write-Output "Starting Service " $item.Name " on server: " $item.Server
$start = Get-Date
$startSVCblock = {param($item) Start-Service -InputObject (Get-Service -ComputerName $item.Server -Name $item.Name)}
$j = Start-Job -ScriptBlock $startSVCblock -Arg $item
do {
if ($j.State -ne 'Running') { break}
$j | Receive-Job
} while (((Get-Date) - $start) -le $timeout)
$newService = Get-Service -ComputerName $item.Server -Name $item.Name
if ($newService.Status -ne "Running") { LogWrite "$item could not start" }
}