Windows Server 2012进程监控脚本监控指定进程的运行状态检测到异常时通过邮件发送告警通知
# Windows Server 2012 进程监控脚本
# 功能:监控指定进程,异常时通过邮件提醒
# 作者:豆包编程助手
# 日期:2025-10-08

# -------------------------- 配置参数 --------------------------
# 需要监控的进程名称数组(不含.exe扩展名)
$processNames = @("notepad", "w3wp", "sqlservr")

# 邮件通知配置
$smtpServer = "smtp.example.com"        # SMTP服务器地址
$smtpPort = 587                         # SMTP服务器端口
$smtpUseSSL = $true                     # 是否使用SSL加密
$smtpUsername = "alert@example.com"     # 发送邮件的账号
$smtpPassword = "your_password"         # 发送邮件的密码
$fromAddress = "server-alert@example.com"  # 发件人地址
$toAddresses = @("admin1@example.com", "admin2@example.com")  # 收件人地址数组
$emailSubject = "【服务器告警】进程异常监控通知"  # 邮件主题

# 监控配置
$checkInterval = 60                     # 检查间隔(秒)
$maxRestartAttempts = 2                 # 最大自动重启尝试次数
$logFile = "C:\Logs\ProcessMonitor.log" # 日志文件路径
# --------------------------------------------------------------

# 创建日志目录(如果不存在)
$logDir = Split-Path $logFile -Parent
if (-not (Test-Path $logDir)) {
    New-Item -ItemType Directory -Path $logDir | Out-Null
}

# 写入日志函数
function Write-Log {
    param([string]$message)
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "[$timestamp] $message"
    Add-Content -Path $logFile -Value $logEntry
    Write-Host $logEntry
}

# 发送邮件通知函数
function Send-AlertEmail {
    param(
        [string]$processName,
        [string]$status
    )
    
    $body = @"
    <html>
    <body>
    <h2>服务器进程异常告警</h2>
    <p>时间: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")</p>
    <p>服务器: $($env:COMPUTERNAME)</p>
    <p>进程: $processName.exe</p>
    <p>状态: $status</p>
    <p>请及时检查相关服务状态。</p>
    </body>
    </html>
"@
    
    try {
        $smtpPasswordSecure = ConvertTo-SecureString $smtpPassword -AsPlainText -Force
        $smtpCredential = New-Object System.Management.Automation.PSCredential ($smtpUsername, $smtpPasswordSecure)
        
        Send-MailMessage -From $fromAddress `
                        -To $toAddresses `
                        -Subject $emailSubject `
                        -Body $body `
                        -BodyAsHtml `
                        -SmtpServer $smtpServer `
                        -Port $smtpPort `
                        -UseSsl $smtpUseSSL `
                        -Credential $smtpCredential
        
        Write-Log "已发送告警邮件: $processName.exe - $status"
    }
    catch {
        Write-Log "发送邮件失败: $_"
    }
}

# 重启进程函数
function Restart-ProcessSafely {
    param([string]$processName)
    
    $attempts = 0
    $restarted = $false
    
    while ($attempts -lt $maxRestartAttempts -and -not $restarted) {
        $attempts++
        Write-Log "尝试重启进程 $processName.exe (第 $attempts 次)"
        
        try {
            # 检查是否有残留进程并结束
            $existingProcess = Get-Process -Name $processName -ErrorAction SilentlyContinue
            if ($existingProcess) {
                $existingProcess | Stop-Process -Force -ErrorAction Stop
                Write-Log "已强制结束 $processName.exe 进程"
                Start-Sleep -Seconds 5
            }
            
            # 启动进程(这里假设进程在默认路径,实际使用时请修改为正确路径)
            $processPath = "C:\Program Files\$processName\$processName.exe"
            if (Test-Path $processPath) {
                Start-Process -FilePath $processPath -ErrorAction Stop
                Write-Log "成功启动 $processName.exe 进程"
                $restarted = $true
            }
            else {
                Write-Log "未找到进程路径: $processPath"
                break
            }
        }
        catch {
            Write-Log "重启进程失败: $_"
            Start-Sleep -Seconds 10
        }
    }
    
    return $restarted
}

# 主监控循环
Write-Log "进程监控脚本已启动,监控进程: $($processNames -join ', ')"

while ($true) {
    foreach ($processName in $processNames) {
        try {
            # 检查进程是否在运行
            $process = Get-Process -Name $processName -ErrorAction SilentlyContinue
            
            if (-not $process) {
                $message = "进程 $processName.exe 未在运行"
                Write-Log $message
                
                # 尝试自动重启进程
                $restartSuccess = Restart-ProcessSafely -processName $processName
                
                if ($restartSuccess) {
                    Send-AlertEmail -processName $processName -status "已停止运行,已成功重启"
                }
                else {
                    Send-AlertEmail -processName $processName -status "已停止运行,自动重启失败,请手动处理"
                }
            }
            else {
                # 检查进程是否响应
                if (-not $process.Responding) {
                    $message = "进程 $processName.exe 无响应 (PID: $($process.Id))"
                    Write-Log $message
                    Send-AlertEmail -processName $processName -status "无响应,PID: $($process.Id)"
                    
                    # 尝试重启无响应的进程
                    Restart-ProcessSafely -processName $processName | Out-Null
                }
                else {
                    Write-Log "进程 $processName.exe 运行正常 (PID: $($process.Id))"
                }
            }
        }
        catch {
            Write-Log "监控进程 $processName.exe 时发生错误: $_"
        }
    }
    
    # 等待下一次检查
    Write-Log "等待 $checkInterval 秒后进行下一次检查..."
    Start-Sleep -Seconds $checkInterval
}

脚本功能说明

这个进程监控脚本提供了以下核心功能:
  1. 多进程监控:可以同时监控多个指定的进程
  2. 异常检测:检测进程是否停止运行或无响应
  3. 自动恢复:尝试自动重启异常进程
  4. 告警通知:通过邮件发送异常情况通知
  5. 日志记录:详细记录监控过程和事件

使用说明

  1. 配置修改
    • 在脚本开头的配置区域,修改需要监控的进程名称($processNames
    • 配置邮件服务器信息,确保能够正常发送邮件
    • 根据需要调整检查间隔、重启尝试次数等参数
  2. 进程重启路径
    • 脚本中默认的进程启动路径可能需要根据实际情况修改
    • Restart-ProcessSafely函数中调整$processPath变量
  3. 运行方式
    • 以管理员身份打开 PowerShell
    • 运行命令:
      Set-ExecutionPolicy RemoteSigned​
    • 执行脚本:
      .\ProcessMonitor.ps1
  4. 设置为服务
    • 可以使用 NSSM 等工具将脚本注册为 Windows 服务
    • 确保服务以管理员权限运行,以便能够重启系统进程
注意:使用前请先测试邮件配置是否正常,确保在进程异常时能够收到告警信息。对于关键业务进程,建议同时配置多重监控方式。
打赏
Windows Server 2012自动备份脚本PowerShell编写利用Windows Server自带的Windows Server Backup功能来实现自动备份
上一篇
2025年幽冥传奇手游添加自动假人自动打怪完整代码
下一篇
博主索奈
Sonay
28 文章
0 评论
0 收藏
生成中...
二维码标题