[PowerShell]檢查服務並且重新自動啟動
這幾天有朋友丟了一個問題過來,他有一個系統會連接資料庫,該系統是一個服務,但如果某些時候資料庫再進行維護或者是有問題無法連接的時候,該服務雖然會讓某個程序重新連接,但重新連線數次之後,就會自動關閉,但該服務看起來卻顯示正常的,此時必須要把該服務重新啟動才可以。雖然看起來是很容易的事情,但卻困擾朋友許久,因為不知道何時是失效的,每次都是使用者無法使用的時候才被通知,甚至是休假的時候都要想辦法來連線重新啟動服務。
聽完他的說明之後,剛好前一陣子在準備 70-410 考試的時候,看了一些 PowerShell 的指令,因此想說可以試試看利用 PowerShell 配合 Windows 工作排程來解決他的問題
$Logfile = "C:\Temp\$(gc env:computername)_AutoStart.log"
$ServiceName = "MSSQLSERVER"
$PROCESSNAME = "QQ"
# Log
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
# 利用 Get-WmiObject 取得服務,為了要取得服務的啟動模式
Function GetService
{
$Service = Get-WmiObject -Class win32_service |Where-Object{$_.name -eq $ServiceName} -ErrorAction SilentlyContinue
RETURN $Service
}
# 啟動服務
Function StartSerivce
{
ECHO "Start Service"
LogWrite "$(Get-Date)`tStart service :$ServiceName"
Start-Service -Name $ServiceName
LogWrite "$(Get-Date)`tService [$ServiceName] state :$((Get-Service -Name $ServiceName).Status) "
}
# 關閉服務
Function StopSerivce
{
ECHO "Stop Service"
LogWrite "$(Get-Date)`tStop service :$ServiceName"
Stop-Service -Name $ServiceName
LogWrite "$(Get-Date)`tService [$ServiceName] state :$((Get-Service -Name $ServiceName).Status) "
}
$Service = GetService
IF ( $Service -eq $null )
{
ECHO "NO Service"
}
ELSEIF ( $Service.State -eq "Running" )
{
$A = Get-Process -Name $PROCESSNAME -ErrorAction SilentlyContinue
IF ($A -eq $null )
{
StopSerivce
StartSerivce
}
}
ELSEIF ( $Service.State -eq "Stopped" -And $Service.StartMode -eq "Auto" )
{
StartSerivce
}
接下來就要放到他們的環境上執行,因為我的開發環境是 Windows 8.1 和 Windows Server 2012,因此預設的 ExecutionPolicy 設定為「RemoteSigned」,所以可以很容易的來執行。但如果是在 Windows Server 2008 的環境時,因為預設定執行政策是「Restricted」,因此需要用使用 PowerShell 的指令來做變更。
這個是預設沒有變更的狀況
再進入 PowerShell 下利用 「Set-ExecutionPolicy」設定為 「RemoteSigned」
此時利用「伺服器管理員」→「設定」→「工作排程器」→「建立工作」來建立一個排程,讓系統每五分鐘檢查一次,因為在我們的 PowerShell 指令裡面會去啟動和關閉服務,因此在排程設定的時候,要特別加入勾選「以最高權限執行」。
這樣就完成相關設定了,如果系統在某些狀況有重新啟動服務,後續我們也可以重 LOG 檔案中知道發生的時間和次數,也就可以再來查看為什麼那些原因會有失敗的狀況發生囉。
PS. 在前面的 Script ,因為不方便寫出他們所使用的產品名稱,因此我先把服務名稱設定為「MSSQLSERVER」,執行序的名稱為「QQ」,如果你要參考這段 Script 指令的話,記得更改一下對應你所需要的部分就可以了。