0

我必须为我的实习做一个作业,我不知道为什么条件不起作用。我正在尝试使用 VBscript 获取除少数几个之外的所有 windowsservices 并将其写入文本文件。虽然我没有编程经验,但我在这里不知所措。你们能弄清楚这段代码有什么问题吗:

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
4

3 回答 3

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) 以“自然”的方式处理选择/跳过问题(If ... Else ... End If):

  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
...
于 2013-02-24T15:10:56.667 回答
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
于 2013-02-25T16:43:16.183 回答
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 _
于 2013-02-24T14:10:48.253 回答