![自動服務未啟動時的電子郵件通知 (Windows Server 2012 R2)](https://rvso.com/image/668797/%E8%87%AA%E5%8B%95%E6%9C%8D%E5%8B%99%E6%9C%AA%E5%95%9F%E5%8B%95%E6%99%82%E7%9A%84%E9%9B%BB%E5%AD%90%E9%83%B5%E4%BB%B6%E9%80%9A%E7%9F%A5%20(Windows%20Server%202012%20R2).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" }
}