VBscript对每个脚本都有条件

VBscript对每个脚本都有条件,vbscript,wql,Vbscript,Wql,我必须为我的实习做一个作业,我不明白为什么这个条件不起作用。 我正在尝试获取所有的Windows服务,除了一些带有VBscript的服务,并将其写入文本文件。虽然我没有编程经验,但我在这里不知所措。你们能找出这段代码的错误吗: Const ForAppending = 8 Set objFSO = CreateObject("Scripting.FileSystemObject") Set objTextFile = objFSO.OpenTextFile _ ("D:\Beheer\Scrip

我必须为我的实习做一个作业,我不明白为什么这个条件不起作用。 我正在尝试获取所有的Windows服务,除了一些带有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

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

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

第三,在VBScript中,跨越多行的语句(如
if
)需要在除最后一行之外的所有行的末尾加下划线(

因此,改变:

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


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

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

第三,在VBScript中,跨越多行的语句(如
if
)需要在除最后一行之外的所有行的末尾加下划线(

因此,改变:

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


以更结构化的方式处理此类问题:

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

输出:

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
0         Adobe Flash Player Update Service
1 skipped Alerter
2         Application Layer Gateway Service
3 skipped Application Management
4         ASP.NET State Service
...
(2) 在临时文件中重定向输出(进一步参考,请参阅下面的步骤(5))

(3) 以“自然”的方式解决选择/跳过问题(如果…否则…如果结束):

如果你把

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 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
0         Adobe Flash Player Update Service
1 skipped Alerter
2         Application Layer Gateway Service
3 skipped Application Management
4         ASP.NET State Service
...
让它“工作”

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

  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(..)=空的
行序列,并通过注释in/out来启用/禁用当前选择。这也可以避免打字错误引起的意外

更新:

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) 从最简单的脚本开始(列出所有服务):

输出:

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
0         Adobe Flash Player Update Service
1 skipped Alerter
2         Application Layer Gateway Service
3 skipped Application Management
4         ASP.NET State Service
...
(2) 在临时文件中重定向输出(进一步参考,请参阅下面的步骤(5))

(3) 以“自然”的方式解决选择/跳过问题(如果…否则…如果结束):

如果你把

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 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
0         Adobe Flash Player Update Service
1 skipped Alerter
2         Application Layer Gateway Service
3 skipped Application Management
4         ASP.NET State Service
...
让它“工作”

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

  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(..)=空的
行序列,并通过注释in/out来启用/禁用当前选择。这也可以避免打字错误引起的意外

更新:

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
...

这里有两个非常详细的答案,可以解释你错过了什么。使用
Dictionary
as@Ekkehard.Horner建议在这种情况下应该是最优化的方法,因为您有大量的值要比较。但是也可以尝试一下
Select Case
,就像其他类似任务一样。在
选择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

这里有两个非常详细的答案,可以解释你错过了什么。使用
Dictionary
as@Ekkehard.Horner建议在这种情况下应该是最优化的方法,因为您有大量的值要比较。但是也可以尝试一下
Select Case
,就像其他类似任务一样。在
选择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

-0.49您无法将objServerice与字符串进行比较,必须使用objServerice.DisplayName。很抱歉,这是一个有害程序,但现在“u”(请继续使用行标记)在
后出现错误。(+1;谢谢你的改进。)@Ekkehard.Horner:你说得对。当您尝试运行解析器时,它必须提示这一点。-0.49您无法将objservice与字符串进行比较,必须使用objservice.DisplayName。很抱歉,这是一个有害程序,但现在“_”(请继续使用行标记)在
s之后出现错误。(+1;谢谢你的改进。)@Ekkehard.Horner:你说得对。当您尝试运行解析器时,它必须提示这一点。您希望发生什么,它以什么方式“不起作用”?您希望发生什么,它以什么方式“不起作用”?最好使字典中的键不区分大小写:
dicSkip.CompareMode=vbTextCompare
感谢您的详细解释。这种方法唯一的问题是它将