每个都有VBscript条件

时间:2013-02-24 14:01:03

标签: vbscript wql

我必须为我的实习做一项任务,我无法弄清楚为什么条件不会起作用。 我试图获得所有的windowsservices,除了一些VBscript,并将其写入文本文件。虽然我没有编程经验,但我在这里不知所措。你们可以弄清楚这段代码有什么问题:

Const ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
("D:\Beheer\Scripts\Services\Services_For_this_server.txt", ForAppending, True)
Set colServices = GetObject("winmgmts:").ExecQuery _
("Select * from Win32_Service")
For Each objService in colServices 
If objService = "Human Interface Device Access" OR
    "Health Key and Certificate Management" OR
    "IKE and AuthIP IPsec Keying Modules" OR
    "PnP-X IP Bus Enumerator" OR
    "IP Helper" OR
    "CNG Key Isolation" OR
    "KtmRm for Distributed Transaction Coordinator" OR
    "Server" OR
    "Workstation" OR
    "Link-Layer Topology Discovery Mapper" OR
    "TCP/IP NetBIOS Helper" OR
    "Multimedia Class Scheduler" OR
    "Windows Firewall" OR
    "Distributed Transaction Coordinator" OR
    "Microsoft iSCSI Initiator Service" OR
    "Windows Installer" OR
    "Network Access Protection Agent" OR
    "Netlogon" OR
    "Network Connections" OR
    "Network List Service" OR
    "Network Location Awareness" OR
    "Network Store Interface Service" OR
    "Performance Counter DLL Host" OR
    "Performance Logs & Alerts" OR
    "Plug and Play" OR
    "IPsec Policy Agent" OR
    "Power" OR
    "User Profile Service" OR
    "Protected Storage" OR
    "Remote Access Auto Connection Manager" OR
    "Remote Access Connection Manager" OR
    "Routing and Remote Access" OR
    "Remote Registry" OR
    "RPC Endpoint Mapper" OR
    "Remote Procedure Call (RPC) Locator" OR
    "Remote Procedure Call (RPC)" OR
    "Resultant Set of Policy Provider" OR
    "Special Administration Console Helper" OR
    "Security Accounts Manager" OR
    "Smart Card" OR
    "Task Scheduler" OR
    "Smart Card Removal Policy" OR
    "Secondary Logon" OR
    "System Event Notification Service" OR
    "Remote Desktop Configuration" OR
    "Internet Connection Sharing (ICS)" OR
    "Shell Hardware Detection" OR
    "SNMP Trap" OR
    "Print Spooler" OR
    "Software Protection" OR
    "SPP Notification Service" OR
    "SSDP Discovery" OR
    "Secure Socket Tunneling Protocol Service" OR
    "Microsoft Software Shadow Copy Provider" OR
    "Telephony"
THEN ""
ELSE
objTextFile.WriteLine(objService.DisplayName)
Next
objTextFile.Close

3 个答案:

答案 0 :(得分:2)

以更有条理的方式处理这些问题:

(1)从最简单的脚本开始(列出所有服务):

  Dim colServices : Set colServices = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service")
  Dim n           : n               = 0
  Dim objService
  For Each objService in colServices
      WScript.Echo n, objService.DisplayName
      n = n + 1
  Next

输出:

0 Adobe Flash Player Update Service
1 Alerter
2 Application Layer Gateway Service
3 Application Management
4 ASP.NET State Service
5 Windows Audio
6 Background Intelligent Transfer Service
...

105 Automatic Updates
106 Wireless Zero Configuration
107 Network Provisioning Service

(2)将输出重定向到临时文件中(供进一步参考;参见下面的步骤(5))

(3)以“自然”的方式处理选择/跳过问题(如果...等等......结束如果):

  Dim colServices : Set colServices = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service")
  Dim n           : n               = 0
  Dim objService
  For Each objService in colServices
      Dim sSkipped : sSkipped = Space(7)
      [insertion point]
      WScript.Echo n, sSkipped, objService.DisplayName
      n = n + 1
  Next

如果你把

If objService = "Alerter" Then sSkipped = "skipped"

进入插入点,你得到一个'对象不支持此属性或方法'运行时错误。在

中使用.DisplayName
If objService.DisplayName = "Alerter" Then sSkipped = "skipped"

'作品':

0         Adobe Flash Player Update Service
1 skipped Alerter
2         Application Layer Gateway Service
3         Application Management

然后尝试:

  If objService.DisplayName = "Alerter" Or
     objService.DisplayName = "Application Management" Then sSkipped = "skipped"

引发语法错误,

  If objService.DisplayName = "Alerter" Or _
     objService.DisplayName = "Application Management" Then sSkipped = "skipped"

输出:

0         Adobe Flash Player Update Service
1 skipped Alerter
2         Application Layer Gateway Service
3 skipped Application Management
4         ASP.NET State Service
...

让它'工作'。

(4)原则上解决了问题后,您可以考虑解决方案的缺点和可能的增强/改进。在Or条款的长连接序列中编辑是很麻烦的;一个标准的出路/周围使用字典:

  Dim colServices : Set colServices = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service")
  Dim dicSkip     : Set dicSkip     = CreateObject("Scripting.Dictionary")
  dicSkip("Alerter"               ) = Empty
  dicSkip("Application Management") = Empty
  WScript.Echo "planning to skip:", Join(dicSkip.Keys(), ", ")
  Dim n           : n               = 0
  Dim objService
  For Each objService in colServices
      Dim sSkipped : sSkipped = Space(7)
      If dicSkip.Exists(objService.DisplayName) Then sSkipped = "skipped"
      WScript.Echo n, sSkipped, objService.DisplayName
      n = n + 1
  Next

现在易于维护数据结构

  dicSkip("Alerter"               ) = Empty
  dicSkip("Application Management") = Empty

取代了更复杂的控制结构。

(5)您甚至可以使用完整列表的转储(步骤2)和一些编辑器宏来创建dicSkip(..) = Empty行的完整序列,并通过注释/注释来启用/禁用当前选择。这样可以避免由错别字引起的意外。

<强>更新

type servicedump.vbs

Option Explicit

Const sOutFSpec = ".\servicedump.txt"

Dim goFS        : Set goFS        = CreateObject("Scripting.FileSystemObject")
Dim oOutFile    : Set oOutFile    = goFS.CreateTextFile(sOutFSpec, True)
Dim colServices : Set colServices = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service")
Dim dicSkip     : Set dicSkip     = CreateObject("Scripting.Dictionary")
dicSkip("Alerter"               ) = Empty
dicSkip("Application Management") = Empty
Dim objService
For Each objService in colServices
    If Not dicSkip.Exists(objService.DisplayName) Then oOutFile.WriteLine objService.DisplayName
Next
oOutFile.Close

cscript servicedump.vbs

type servicedump.txt
Adobe Flash Player Update Service
Application Layer Gateway Service
ASP.NET State Service
Windows Audio
...

答案 1 :(得分:2)

嗯,你有2个很好的非常详细的答案,解释你错过了什么。在这种情况下,使用Dictionary作为@ Ekkehard.Horner建议应该是最优化的方式,因为您有大量要比较的值列表。但是也可以试试Select Case,作为其他类似任务的替代方案。在Select Case中,您可以使用以逗号分隔的值列表,例如:

'instead of...
For obj In Collection
    If obj.property = "X" Or _
    obj.property = "Y" Or _
    obj.property = "Z" Then
        '...
    Else
        '...
Next

'you can...
For obj In Collection
    Select Case obj.property
        Case "X", "Y", "Z"
            'skip (or whatever)
        Case Else
            'write (or whatever)
    End Select
Next

答案 2 :(得分:1)

首先,字符串本身不是条件。而不是重复字符串,重复条件。该条件由=运算符组成,其中任一侧都有变量。示例条件是answer = 42

其次,您将对象与字符串进行比较。正如Ekkehard Horner所评论的那样,您应该比较DisplayName对象的objService属性。

第三,在VBScript中,跨越多行的语句(如if)需要在最后一行的末尾添加下划线(_)。

所以改变:

If objService = "Human Interface Device Access" OR
    "Health Key and Certificate Management" OR

要:

If objService.DisplayName = "Human Interface Device Access" OR _
    objService.DisplayName = "Health Key and Certificate Management" OR _