【问题标题】:Status check of service is failing服务状态检查失败
【发布时间】:2015-12-29 21:23:43
【问题描述】:

我正在使用 Windows 2008 Server R2。我发现这个 VBScript 应该检查服务是启动还是停止。

这是脚本:

'Declare Variables
Dim objWMIService, objProcess, colProcess, Status, strComputer, strService

'Assign Arguments
strComputer = WScript.Arguments(0)
strService = WScript.Arguments(1) 
Status = False

'Check For Arguments - Quit If None Found
If Len(strService) < 1 Then
    Wscript.echo "No Arguments Entered - Exiting Script"
    WScript.Quit
End If

'Setup WMI Objects
Set objWMIService = GetObject("winmgmts:"& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set colProcess = objWMIService.ExecQuery ("SELECT DisplayName, Status, State FROM Win32_Service WHERE DisplayName = '" & strService & "'")

'Check For Running Service
For Each objProcess In colProcess
    If InStr(objProcess.DisplayName, strService) > 0 And objProcess.State = "Running" Then
        Status = True
    End If
Next

If Status = True Then
    WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Running"
Else
    WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Not Running"
End If

通过命令行我这样调用脚本

CSCRIPT ServiceCheckScript.vbs LOCALHOST "Print Spooler"

命令行的响应是

...\ServiceCheckScript.vbs(20, 1) (null): 0x80041017

我看到 0x80041017 错误是指查询返回空值的结果,但我不确定为什么会这样。

【问题讨论】:

  • 在我的 Windows 7 机器上运行良好。出于某种原因,错误代码提醒我 WMI 损坏时返回的错误代码。试试这个:开始>运行> wbemtest(打开它)>连接>连接>查询>[类型]select * from win32_service>应用。如果您在任何时候遇到错误(包括单击“连接”时,不包括您在查询中打错字),那么您的 WMI 已损坏。
  • 错误 0x8041017 表示您的 query is invalid.仔细检查strService 的值是否符合您的预期(例如,使用WScript.Echo "-" &amp; strService &amp; "-" 之类的语句)。
  • WMI 不使用. 来表示当前机器而不是localhost?猜猜它应该仍然有效,只是一个观察。
  • @Lankymart 绰号允许.localhost、IP 地址或主机名。此外,名字对象字符串的问题应该引发不同的错误(在更早的时候也是如此)。

标签: service command-line vbscript wmi windows-server-2008-r2


【解决方案1】:

上面代码的几个问题:

  1. 验证您从 WMI 查询中获得了结果,这样您就不会尝试使用空值。在if colProcess.count &gt; 0 then 中包装使用结果。

  2. 通过在参数验证中包含您的代码来删除额外的 .quit。使用参数计数比字符串函数wscript.arguments.count = 2 更便宜/更清洁,因为您只是检查以确保它们不为空。如果您需要更复杂的验证,则需要更多的逻辑。

  3. 没有任何理由使用 instr(objProcess.Displayname, strService),因为您的 WMI 查询已经指定结果等于其中的服务显示名称 where DisplayName = strService

  4. 在循环内执行服务状态的条件检查更简单/更清晰。

这是我的例子。

'Declare Variables
Dim objWMIService, objProcess, colProcess, Status, strComputer, strService

'Verify arguments were passed
if WScript.Arguments.Count = 2 then
   'Assign Arguments
   strComputer = WScript.Arguments(0)
   strService = WScript.Arguments(1) 

   'Setup WMI Objects
   Set objWMIService = GetObject("winmgmts:"& "{impersonationLevel=impersonate}!\\" & _
                       strComputer & "\root\cimv2") 
   Set colProcess = objWMIService.ExecQuery ("SELECT DisplayName, Status, State FROM " & _
                    "Win32_Service WHERE DisplayName = '" & strService & "'")

   'Ensure there were results returned
   if colProcess.count > 0 then
      'Check For Running Service
      For Each objProcess In colProcess
         If objProcess.State = "Running" Then
            WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Running"
         else
            WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Not Running"
         End If
      Next
   else
      WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Does not exist"
   end if
end if

编辑:只需添加,我在 Win 8.1 和 Server 2012R2 中都使用有效和无效的服务名称验证了上述代码。但是,我会添加更多错误检查,例如验证计算机参数是否有效,以确保您的 WMI 查询不会不必要地/莫名其妙地失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多