WindowsのプロセスがハングアップしているかをPowerShellで検知し、プロセスID単位でプロセスをKILLするスクリプトです。
たぶん需要あります。
Powershellでプロセスハング監視&KILLスクリプト
簡単な仕様説明
- プロセスID(PID)をCSVフォーマットで取得
- PID単位のCPUTIMEを取得する
- CPUTIMEがカウントアップされない=ハング
- ハングしているPIDをKILL
スクリプトソース
#----- ログローテート、ログの設定
CD D:\work\log
FORFILES /P D:\work\log /D -60 /M HangKill_*.log /C "CMD /C DEL @file" >${NULL} 2>&1
$LOG = "HangKill_" +(Get-Date -Format "yyyyMMdd")+ ".log"
#----- PIDの取得
$TASK = TASKLIST /SVC /FI "IMAGENAME EQ iexplore.exe" /NH /FO:CSV
#----- ","でスプリット
$TASK = $TASK -SPLIT ""","""
#----- PIDを取り出す(1カラム目)
$PID1 = $TASK[1]
#----- PIDのCPUTIMEのBeforeとして値を取り出す
$PID1_CPUTIME_BEF = TASKLIST /FI "PID EQ ${PID1}" /V /NH /FO:CSV
$PID1_CPUTIME_BEF = $PID1_CPUTIME_BEF -SPLIT ""","""
$PID1_CPUTIME_BEF = $PID1_CPUTIME_BEF[7]
#----- スリープ
SLEEP 300
#----- PIDのCPUTIMEのAfterとして値を取り出す
$PID1_CPUTIME_AFT = TASKLIST /FI "PID EQ ${PID1}" /V /NH /FO:CSV
$PID1_CPUTIME_AFT = $PID1_CPUTIME_AFT -SPLIT ""","""
$PID1_CPUTIME_AFT = $PID1_CPUTIME_AFT[7]
#----- PID1のCPUTIMEを比較し、時間の増加が無ければプロセスKILL。ループは応用してちょ
IF($PID1_CPUTIME_BEF -EQ $PID1_CPUTIME_AFT){
ECHO "$(Get-Date -Format "HH:mm:ss") PID1:${PID1}プロセスハングアップによりリブート" >> $LOG
TASKKILL /F /PID $PID1
}
#---------- 以降は環境によって処理を変えたりする ----------
#----- プロセスの起動(自動起動とかなら省略してちょ)
Start-Process iexplore.exe
#----- プロセス起動待ちのスリープ
SLEEP 5
#----- 正常稼動確認関数。iexplore.exeの2プロセスをチェック。PIDの取得
$TASK = TASKLIST /FI "IMAGENAME EQ iexplore.exe" /V /NH /FO:CSV
#----- 2プロセスなければクリティカルでアラート
IF($TASK.COUNT -NE 2){
$MSG = "C ${Env:COMPUTERNAME}にてIEにてプロセスチェック異常"
Write-EventLog -LogName Application -Source ScriptKanshi -EventID 999 -Message "これはイベントログのテストメッセージです"
ECHO "$(Get-Date -Format "HH:mm:ss") プロセス数異常" >> $LOG
}
イベントログに出力するなら
イベントログソースを登録しないとエラー
このままではイベントログソースがなく以下のメッセージが出ると思います。
Write-EventLog : ソース名 "ScriptKanshi" はコンピューター "localhost" に存在しません。
発生場所 行:1 文字:15
+ Write-EventLog <<<< -LogName Application -Source ScriptKanshi -EventID 999 -Message "これはイベントログのテストメッセージです"
+ CategoryInfo : InvalidOperation: (:) [Write-EventLog]、InvalidOperationException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteEventLogCommand
イベントログのログソースを登録する
いちおう重複確認する
if ([System.Diagnostics.EventLog]::SourceExists("ScriptKanshi") -eq $false){
New-EventLog -LogName Application -Source ScriptKanshi
}
テストメッセージするよ。
Write-EventLog -LogName Application -EntryType Error -Source ScriptKanshi -EventId 1 -Message "Power Shell Test"
イベントログソースを削除するよ
間違えたときは削除しちゃって。
Remove-EventLog -Source ScriptKanshi
イベントログソースの確認コマンド
ちゃんと登録されたか見てみよう。
レジストリの値をコマンドで見るよ。
Get-ChildItem -Path HKLM:SYSTEM\CurrentControlSet\Services\EventLog\Application
著作権について
著作権は当サイトの管理者に帰属します。
商用利用以外であれば著作権フリーですが、念のためコメントにてお知らせください。
