情景:
我正在尝试找出一种shell脚本方式(命令行方法)来查找某些特定Windows服务的状态。例如,我选择了Telnet服务,它处于禁用模式(从services.msc检查)并且不会进入sc query
命令。
sc query state= all
工作正常并向我提供了所有服务的列表(活动/非活动)。现在我的问题已经减少,以找到从Windows服务显示名称(输出管道)获取服务状态的方法。
我试过sc query state= all | find /N "Telnet"
但是这只会给我搜索行号及其内容,而不是服务状态,因为该信息比显示名称提前2-3行(通过管道搜索并返回)
问题:
在Windows中是否有办法从行号位置管道输出?就像在我的情况下,如果在第182行找到telnet服务,给我从第0行到第187行的命令输出?
如果您有任何想法,请随时告诉我解决问题的更好方法。
非常感谢!!
答案 0 :(得分:1)
这是使用批处理文件执行此操作的一种方法,尽管它不是一个非常优雅的解决方案。
@echo off
setlocal
set currentservice=""
set servicestate=""
sc query state= all > services.txt
for /f "delims=:; tokens=1,2" %%a in (services.txt) do call :findservice "%%a" "%%b"
del services.txt
echo %servicestate%
endlocal
goto :end
:findservice
if not %1 == "SERVICE_NAME" goto :findstate
set currentservice=%2
goto :end
:findstate
if not %1 == " STATE " goto :end
if not %currentservice% == " Telnet" goto :end
set servicestate=%2
goto :end
:end
它首先将sc query
的结果写入临时文件(services.txt)。然后它使用for循环来处理该文件的每一行。
当找到以SERVICE_NAME
开头的行时,它会将该名称的值保存在 currentservice 变量中。然后,当它找到以STATE
开头的行时,如果 currentservice 变量设置为" Telnet"
,则会在 servicestate 中保存状态值变量。
所以在最后,你应该在 servicestate 变量中有某种状态(我在示例代码中回应)。这类似于" 4 RUNNING "
或" 1 STOPPED "
。如果找不到Telnet服务,它将为空白。
请注意,由于sc查询输出的处理方式,代码中的空格都很重要。请特别注意,您尝试匹配的服务名称必须以空格开头。
这可能会有所改善,但至少它是一个开始。
答案 1 :(得分:1)
@dbenham编写了一个名为repl.bat的工具,可以在http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
找到以下面的方式使用它,它提供了一个进程和状态列表:
sc query | findstr "SERVICE_NAME STATE" | repl "SERVICE_NAME..(.*)\r\n" "$1" m | repl "(.*) *STATE.*:....(.*)." "$2 - $1"
这是Win 8 Pro 32位
下的输出示例 RUNNING - wcncsvc
跑步 - WdiServiceHost
运行 - WinDefend
RUNNING - WinHttpAutoProxySvc
运行 - winmgmt
运行 - WPDBusEnum
跑步 - wscsvc
要获得包含服务和显示名称的所有服务的完整列表,可以在此处使用:
sc query state= all | findstr "DISPLAY_NAME: SERVICE_NAME STATE" | repl "SERVICE_NAME..(.*)\r\n" "$1" m | repl "DISPLAY_NAME:.(.*)\r\n" " - $1" m | repl "(.*) *STATE.*: . (.*)." "$2 - $1"
其中提供了这样的列表:
RUNNING - WPDBusEnum - 便携式设备枚举器服务
RUNNING - wscsvc - 安全中心
停止 - WSearch - Windows搜索
STOPPED - WSService - Windows应用商店服务(WSService)
停止 - wuauserv - Windows Update
STOPPED - wudfsvc - Windows Driver Foundation - 用户模式驱动程序框架
停止 - WwanSvc - WWAN AutoConfig
答案 2 :(得分:1)
这是另一种方法。我采取了一些快捷方式,使它有点慢,但它应该在所有具有我期望的SC的Windows版本上运行。
@echo off
for /f "tokens=1,* delims=:" %%a in ('sc query state^= all ^| findstr "DISPLAY_NAME: STATE" ') do (
echo %%a|find "DISP">nul && set /p "=%%b : "<nul
echo %%a|find "STATE">nul && (set /p "=%%b"<nul&echo.)
)
pause
这是输出:
家庭安全:1停止了
便携式设备枚举器服务:4 RUNNING
安全中心:4运行中
Windows搜索:1 STOPPED
Windows应用商店服务(WSService):1 STOPPED
Windows Update:1 STOPPED
Windows Driver Foundation - 用户模式驱动程序框架:1 STOPPED
WWAN AutoConfig:1 STOPPED
答案 3 :(得分:1)
这里有一些代码可以在display_name行上方显示两行,假设您的查询匹配在display_name行中。
“%1”是您所追求的服务名称 - 也使该术语成为唯一。
@echo off
set "n=-1"
sc query state= all |findstr /n "^" >Log.tmp
for /f "delims=:" %%a in (' findstr /i "%~1" ^<log.tmp ') do set n=%%a
set /a n=n+2
for /f "delims=" %%a in (' findstr /i "^%n%:" ^<log.tmp ') do set "line=%%a"
echo "%line%"
del log.tmp
pause
答案 4 :(得分:1)
PowerShell是一种选择吗?它内置于最近的Windows版本中,并将通过简单的命令获得您的服务状态。如果服务显示名称是Windows时间
get-service -DisplayName "windows time" | Select-Object Status