2013-02-24 57 views
0

我必須爲我的實習做一個任務,我無法弄清楚爲什麼條件將無法正常工作。 我試圖讓所有的windowsservices除了一些VBscript,並將其寫入到文本文件。雖然我沒有編程經驗,但我在這裏不知所措。你們能找出這段代碼有什麼問題: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 
+0

你要什麼發生,以及以何種方式它「不工作」? – 2013-02-24 14:23:09

回答

1

首先,一個字符串本身並不是一個條件。重複字符串,而不是重複條件。該條件由一個帶有變量的=運算符組成。示例條件是answer = 42

其次,你正在比較一個對象與一個字符串。正如Ekkehard Horner所評論的,您應該比較objService對象的DisplayName屬性。

第三,在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 _ 
+0

-0.49您無法將objServerice與字符串進行比較,必須使用objServerice.DisplayName。 – 2013-02-24 14:21:02

+0

抱歉是一個有害生物,但現在'_'(請繼續行標記)在'OR's後出現。 (+1;感謝您的改進)。 – 2013-02-24 14:31:46

+0

@ Ekkehard.Horner:你說得對。當你試圖運行它時,解析器必須提示這一點。 – Andomar 2013-02-24 14:56:13

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" 

進入插入點,您會收到一個'Object does not support this property or method'runtime error。使用.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

這可能是一個好主意,使字典中的鍵不區分大小寫:'dicSkip.CompareMode = vbTextCompare' – 2013-02-24 17:30:06

+0

感謝您的詳細解釋。這種方法唯一的問題是,它不會將生成的輸出結果放到一個.txt文件中,我需要這樣做。 – user2104534 2013-02-25 10:28:18

+0

@ user2104534 - 你在拉我的腿嗎? (a)寫入文件是在您發佈的代碼中實現的。 (b)步驟(2)顯示免費獲得文件輸出。 – 2013-02-25 11:37:32

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 
+0

+1 - 當'IF'導致問題時,查看'選擇案例'。 – 2013-02-25 16:49:43