0

设想 :

我正在尝试找出一种 shell 脚本方式(命令行方法)来找出某些特定 Windows 服务的状态。例如,我选择了 Telnet 服务,它处于禁用模式(从 services.msc 中检查)并且不会进入sc query命令。

sc query state= all工作正常,并为我提供了所有服务的列表(活动/非活动)。现在我的问题减少了,以找到一种从 Windows 服务显示名称(输出管道)获取服务状态的方法。

我试过 sc query state= all | find /N "Telnet"了,但这只会给我搜索行号及其内容,而不是服务状态,因为该信息在显示名称之前 2-3 行(通过管道搜索和返回)。

问题 :

windows中有没有办法从行号位置管道输出?就像在我的情况下,如果在第 182 行找到 telnet 服务,给我第 180 到 187 行的命令输出?

如果您有任何想法,请随时让我知道解决我问题的更好方法。

非常感谢 !!

4

5 回答 5

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 位下的输出示例

正在运行 - wcncsvc
正在运行 - WdiServiceHost
正在运行 - WinDefend
正在运行 - 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"

它提供了这样的列表:

正在运行 - WPDBusEnum - 便携式设备枚举器服务
正在运行 - wscsvc - 安全中心
已停止 - WSearch - Windows 搜索
已停止 - WSService - Windows 存储服务 (WSService)
已停止 - wuauserv - Windows 更新
已停止 - wudfsvc - Windows 驱动程序基础 - 用户模式驱动程序框架
已停止- WwanSvc - WWAN 自动配置

于 2013-06-25T00:25:32.617 回答
1

PowerShell是一种选择吗?它内置在最新的 Windows 版本中,将通过一个简单的命令获取您的服务状态。如果服务显示名称是 Windows 时间

get-service -DisplayName "windows time" | Select-Object Status
于 2013-06-25T14:43:13.983 回答
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
于 2013-06-25T11:16:39.083 回答
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 运行
安全中心:4 运行
Windows 搜索:1 停止
Windows 存储服务 (WSService):1 停止
Windows 更新:1 停止
Windows 驱动程序基础 - 用户模式驱动程序框架:1 停止
WWAN 自动配置: 1 停止

于 2013-06-25T06:35:05.587 回答
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 "or " 1 STOPPED "。如果没有找到 Telnet 服务,它将是空白的。

请注意,由于处理 sc 查询输出的方式,代码中的空格都很重要。特别要注意,您尝试匹配的服务名称必须以空格开头。

有可能这可以改进,但至少这是一个开始。

于 2013-06-24T15:18:40.127 回答