PowerShell如何为Windows计划任务分配固定递增编号适配CheckMK监控
可行实现方案
核心逻辑是通过本地持久化文件存储计划任务名和编号的绑定映射,每次脚本运行优先读取已有映射,按规则为新增任务分配编号,更新后回写存储文件,完全可以满足你的三个需求。
核心实现逻辑
- 用和脚本同目录的
task_id_map.json作为持久化存储文件,结构为「任务名: 编号」的键值对 - 新增
$reuseDeletedId配置开关:设为$true时已删除任务的编号会分配给新增任务,设为$false时编号永不复用,永久绑定原任务 - 编号分配规则:
- 已有映射的任务直接使用绑定的编号
- 新增任务如果开启复用,优先取现有映射中最小的未被使用的编号;未开启复用直接取当前最大编号+1
修改后的完整脚本
# Monitor windows tasks for checkmk raw 1.6.0 # Last update: 2024-xx-xx # 配置项:是否复用已删除任务的编号,$false为永不复用 $reuseDeletedId = $false # 映射文件存储路径,默认和脚本同目录 $mapPath = Join-Path $PSScriptRoot "task_id_map.json" # 读取或初始化映射表 if (Test-Path $mapPath) { $taskIdMap = Get-Content $mapPath -Raw | ConvertFrom-Json -AsHashtable } else { $taskIdMap = @{} } # 获取所有当前计划任务 $tasks = Get-ScheduledTask | Get-ScheduledTaskInfo | Select TaskName,LastRunTime,LastTaskResult $currentTaskNames = $tasks.TaskName # 第一步:清理已删除的任务映射(如果开启复用的话需要统计空编号) $existingIds = $taskIdMap.Values | ForEach-Object { [int]$_ } $allocatedIds = @() foreach ($taskName in $taskIdMap.Keys) { if ($currentTaskNames -notcontains $taskName) { # 不保留已删除任务的映射时直接移除,要永久保留的话注释下面这行 $taskIdMap.Remove($taskName) } else { $allocatedIds += $taskIdMap[$taskName] } } # 第二步:为新增任务分配编号 foreach ($task in $tasks) { $taskName = $task.TaskName if (-not $taskIdMap.ContainsKey($taskName)) { if ($reuseDeletedId -and $existingIds.Count -gt $allocatedIds.Count) { # 找最小的未使用编号 $newId = 1 while ($allocatedIds -contains $newId) { $newId++ } } else { # 直接取最大编号+1,无现有编号则从1开始 $newId = ($allocatedIds | Measure-Object -Maximum).Maximum + 1 if ($newId -lt 1) { $newId = 1 } } $taskIdMap[$taskName] = $newId $allocatedIds += $newId } } # 回写更新后的映射表到文件 $taskIdMap | ConvertTo-Json | Out-File $mapPath -Encoding utf8 # 输出CheckMK格式结果 foreach ($task in $tasks) { $taskId = $taskIdMap[$task.TaskName] if ($task.LastTaskResult -eq 0) { Write-Host "0 MWT$taskId - Scheduled task: $($task.TaskName) was successful" } else { Write-Host "2 MWT$taskId - Scheduled task: $($task.TaskName) has failed." } }
注意事项
- 不要随意删除
task_id_map.json文件,否则所有任务编号会重新分配,导致CheckMK服务项匹配失效 - 映射以任务名作为唯一标识,任务重命名会被识别为新任务,分配新的编号
- 如果需要永久保留已删除任务的编号永不复用,只需要注释掉脚本中
$taskIdMap.Remove($taskName)这一行即可
内容的提问来源于stack exchange,提问作者Johny Wave
相关产品推荐
相关产品推荐

