需求
采集Windows计划任务信息,步骤分为:
- 通过脚本获取符合条件的计划任务列表;
- 通过脚本查询指定计划任务的状态和上次运行结果;
分析
其实有了上面的步骤,batch方面就好办多了。
具体思路如下:
- 确认Windows下有获取计划任务信息的命令;
- 测试命令输出的内容是否满足需求;
- 清理命令输出内容,精简至所需结果;
- 测试,发布。
解决方案
有了分析结果,那么就好办了,分为三步:
- 测试计划任务命令;
- 编写计划任务的发现脚本;
- 编写计划任务信息的获取脚本;
计划任务的命令
到微软官方查询了计划任务的命令,Windows中有提供schtasks.exe
这个程序。学习下使用。
基本信息获取(不能使用/nh参数):
schtasks.exe /query | findstr “Taskname1 Taskname2"
Folder: \
TaskName Next Run Time Status
======================================== ====================== ===============
Taskname1 N/A Disabled
Taskname2 N/A Disabled
获取所有计划任务的人物名、状态和上次运行结果:
for /f "tokens=2,5,9" %a in ('schtasks.exe /query /v /nh') do @echo %a %b %c
增加具体计划任务的过滤:
for /f "tokens=2,5,9" %a in ('schtasks.exe /query /v /nh') do @echo %a %b %c | findstr "taskname1 taskname2 …"
如果上述命令放在batch里,上述命令的变量就需要加入%
,如%%a
。
其中,上次运行结果的字段为16进制,输出为10进制,注意转换。
因部分计划任务的名称中含有空格,可以考虑将注释提取出来。
计划任务的自动发现
使用方法:schtasksdiscovery.bat "name1 name2 name3"
REM 计划任务的自动发现
REM schtasksdiscovery.bat "name1 name2 name3"
@echo off
@setlocal enabledelayedexpansion
REM IMPORTANT!!! ext is bat.
REM discovery all want monitored scheduled tasks name.
set "str={ ^"data^":["
if NOT [%1]==[] (set "para=%*") else set "para=none"
for /f "tokens=2 delims=," %%a in ('schtasks.exe /query /v /nh /fo csv ^| findstr %para%') do set "str=!str! {"{#SCHTASKNAME}^":^%%a^},"
if "%str:~-1,1%"=="," set "str=%str:~0,-1%"
set "str=%str% ] }"
echo %str%
计划任务信息的采集
使用方法:schtaskstat.bat taskname
REM 计划任务信息的采集
schtaskstat.bat taskname
@echo off
REM IMPORTANT!!! ext is bat.
REM get status of specified task
for /f "tokens=5,9" %%a in ('schtasks.exe /query /v /nh /fo csv^| findstr "%1"') do @echo %%a %%b
其他
该脚本在Windows2003、2008上执行通过。下面说说其他未能解决的问题。
语言包问题
部分机器由于本地语言包问题,在执行schtasks.exe /query
命令的时候会报错:
错误: 无法加载列资源。
此时,如果是在命令行中,可以使用chcp 437
,并修改脚本中的2,5,9
为2,5,10
。可以得到正确的结果。
但是会发现,chcp 437
执行后是新开了一个子进程。经过测试这种方法至少在Zabbix中不能正常使用,依旧是乱码。无论chcp怎么加入,都无法正常生效。
结果返回问题
因为遇到部分系统仅在运行时返回状态Running,其他情况下为空,因此考虑使用/fo csv方式来进行处理。
网友评论