Windows Server 计划任务实战:日志清理与定时巡检自动化
背景:MES 服务器的运维债
上周三早上,产线班长打电话说看板数据不刷新了。远程登上去一看——IIS 日志目录吃了 47GB,系统盘只剩 300MB 可用空间,W3SVC 服务因为磁盘满而停止写入。手动清理完日志、重启服务,看板恢复了,但这是第三次了。
我们的 MES 系统跑在 Windows Server 2019 上,IIS 承载 .NET 应用,SQL Server 存生产数据。运维上存在三个痛点:IIS 日志无限增长、数据库备份全靠手动、服务挂了只能等产线反馈。是时候用任务计划程序把这三件事彻底自动化了。
整体方案
用 Windows 自带的任务计划程序(Task Scheduler)配合 PowerShell 脚本,实现三件事:
- IIS 日志自动清理:每天凌晨 2 点删除 7 天前的日志
- SQL Server 定时备份:每天凌晨 3 点全量备份,保留 14 天
- 服务健康巡检:每 5 分钟检测关键服务状态,异常时尝试重启并发邮件
一、IIS 日志自动清理
IIS 默认把日志写在 C:\inetpub\logs\LogFiles\W3SVC1\,按天生成 u_exYYMMDD.log 文件。不做清理的话,高频采集的 MES 站点每月增长 5-10GB。
PowerShell 脚本 C:\Scripts\Clean-IISLogs.ps1:
# 清理 7 天前的 IIS 日志
$logPath = "C:\inetpub\logs\LogFiles\W3SVC1"
$retainDays = 7
$cutoff = (Get-Date).AddDays(-$retainDays)
Get-ChildItem -Path $logPath -Filter "*.log" |
Where-Object { $_.LastWriteTime -lt $cutoff } |
ForEach-Object {
Remove-Item $_.FullName -Force
Write-Output "$(Get-Date) 已删除: $($_.Name)"
}
# 磁盘空间低于 5GB 时输出告警
$free = (Get-PSDrive C).Free / 1GB
if ($free -lt 5) {
Write-Output "WARNING: C 盘剩余空间仅 $([math]::Round($free,1))GB"
}
注册任务计划程序:
schtasks /create /tn "MES-CleanIISLogs" ^
/tr "powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\Clean-IISLogs.ps1" ^
/sc daily /st 02:00 /ru SYSTEM /f
关键参数:/ru SYSTEM 让任务以系统权限运行,不依赖用户登录;-ExecutionPolicy Bypass 绕过 PowerShell 执行策略限制,只对本次调用生效。
二、SQL Server 定时备份
MES 数据库不能只靠人肉备份。用 PowerShell 调用 Backup-SqlDatabase cmdlet,压缩备份并自动清理过期文件:
# MES 数据库定时备份
$instance = "localhost"
$dbName = "OrBitMOM_YFCOB"
$backupDir = "D:\Backup\MES"
$retainDays = 14
if (!(Test-Path $backupDir)) { New-Item -ItemType Directory -Path $backupDir }
$stamp = Get-Date -Format "yyyyMMdd_HHmmss"
$bakFile = "$backupDir\${dbName}_$stamp.bak"
Backup-SqlDatabase -ServerInstance $instance -Database $dbName `
-BackupFile $bakFile -CompressionOption On
# 清理过期备份
Get-ChildItem -Path $backupDir -Filter "*.bak" |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$retainDays) } |
Remove-Item -Force
Write-Output "$(Get-Date) 备份完成: $bakFile"
注册任务(每天凌晨 3 点):
schtasks /create /tn "MES-DBBackup" ^
/tr "powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\Backup-MESDB.ps1" ^
/sc daily /st 03:00 /ru SYSTEM /f
如果服务器没装 SQL Server PowerShell 模块(SSMS 未完整安装时常缺),用 sqlcmd 替代:
sqlcmd -S localhost -Q "BACKUP DATABASE [OrBitMOM_YFCOB] TO DISK='D:\Backup\MES\daily.bak' WITH FORMAT, COMPRESSION, STATS=10"
三、服务健康巡检与告警
MES 关键服务有三个:IIS 的 W3SVC、SQL Server 的 MSSQLSERVER、以及自研的 MES 采集服务(Windows Service)。写巡检脚本,每 5 分钟跑一次,发现停止先尝试自动重启,再发邮件通知:
# 服务健康巡检
$services = @("W3SVC", "MSSQLSERVER", "MESCollector")
$smtpServer = "smtp.qq.com"
$smtpPort = 25
$from = "mes-alert@company.com"
$to = "ops@company.com"
foreach ($svc in $services) {
$s = Get-Service -Name $svc -ErrorAction SilentlyContinue
if ($s -and $s.Status -ne "Running") {
$body = "服务 $svc 当前状态: $($s.Status)`n时间: $(Get-Date)`n主机: $env:COMPUTERNAME"
Send-MailMessage -From $from -To $to `
-Subject "MES 告警: $svc 服务异常" -Body $body `
-SmtpServer $smtpServer -Port $smtpPort
# 尝试自动重启
Start-Service -Name $svc -ErrorAction SilentlyContinue
Write-Output "$(Get-Date) $svc 异常,已尝试重启"
}
}
注册任务(每 5 分钟):
schtasks /create /tn "MES-HealthCheck" ^
/tr "powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\HealthCheck.ps1" ^
/sc minute /mo 5 /ru SYSTEM /f
踩坑记录
- "仅在用户登录时运行"陷阱:任务计划程序创建向导默认勾选这个选项,服务器没人登录就不执行。必须在任务属性里取消勾选,改选"不管用户是否登录都要运行",运行账户设为 SYSTEM 并勾选"使用最高权限"。
- PowerShell 执行策略:默认 Restricted 策略会阻止 .ps1 脚本运行。不要全局改成 Unrestricted(安全风险),在 schtasks 的 /tr 参数里加
-ExecutionPolicy Bypass即可,只对当前进程生效。 - 脚本路径含空格:如果脚本放在
C:\Program Files\Scripts\下,schtasks 的 /tr 参数会解析失败。最省心的办法是把脚本放在无空格路径(如C:\Scripts\),或者在路径外层加转义引号。 - Send-MailMessage 的 SMTP 认证:QQ/企业邮箱需要发件认证,Send-MailMessage 加
-Credential参数,用PSCredential对象传用户名和授权码(不是邮箱密码)。建议把凭据存为加密文件,别硬编码在脚本里。 - 任务计划程序日志在哪看:任务没按预期执行时,打开事件查看器 → 应用程序和服务日志 → Microsoft → Windows → TaskScheduler → Operational,能看到每次任务的触发时间、执行进程和退出码(0x0 = 成功)。
总结
Windows Server 的任务计划程序是被严重低估的运维工具——系统自带、稳定可靠、SYSTEM 权限足够操作 IIS 和 SQL Server。三个脚本加起来不到 100 行 PowerShell,解决了盯了半年的三块心病。部署完成后,在事件查看器里确认每个任务的下次运行时间和上次结果码(0x0 = 成功),之后就能安心去盯产线,而不是盯服务器了。