WSHでインストール済みソフトを列挙
PC起動時に、ドメインに参加しているクライアントPCのインストール済みソフトを列挙し、サーバの共有フォルダにテキストファイルで落とすという方法を考えています。
グループポリシーで設定をしたいので、WSH(Windows Script Host)を使ってみることにしました。
実はWSH使うのは初めてなんで、@IT:WSHを始めようをまず読んでみます。
WSHのスクリプトは、よく耳にするVBSciprtでかけるみたいです。
で、GUI版(wscript.exe)とCUI版(cscript.exe)があるようです。
コマンドプロンプトでWSH実行するときに使い分けれるようです。
wscript test.vbs GUI版で実行
cscript test.vbs CUI版で実行
GUI,CUI版の違いについては、WscriptとCscriptの違い-WSH@Workshopが参考になります。
で、本題のインストールソフト列挙ですが、最初試したの下記のMicrosoftにあったサンプルです。
WMIで列挙する方法ですね。
しかし、実行すると For ループの Next で (null): 0x80041001 のエラーとなります。
MS TechNet:Windows Management Instrumentation の秘密 トラブルシューティングとヒントを見てみたところ、クラス接続失敗してるっぽいです。
とりあえずデバッグしてみることに。。。
WSH のデバッグ方法とOS側設定 更新版 - しおそるとと、WSH のデバッグ方法とOS側設定 - しおそるとを見て、Windows Script Debuggerを入れてみました。
Windows Script Debuggerはここからダウンロードできるようです。
Windows Script Debuggerを起動して、コマンドプロンプトより、//x オプション付きで実行するとデバッグができるようです。
D:\>cscript //x test.vbs
しかし、確かにデバッグできるようになりましたが、コマンドウィンドウで "? 変数" とすると固まるし、null が発生する箇所に来ても固まります。
Office についてくるらしい Microsoft Script Editor でも試してみましたが、IDEは立ち上がりますがデバッガが起動しません。
仕方ないからWMI使わない方法にしました。
ほぼ、はてな であがってたコードそのままですが、実行するとDドライブ直下にホスト名のテキストファイルでインストールソフトのリストが列挙されます。
Option Explicit
On Error Resume Next
Const HKEY_LOCAL_MACHINE = &H80000002
Dim objRegProv, ccSubKeys
Dim strComputer, sytKey, strSubKey, dwVal
Dim strDisplayName, strParentKeyName, dwSystemComponent
Dim objTextFile
Dim objFSO
Dim computername
Dim objNetWork
'WScript.CreateObject("WScript.Network") がダメなときは日付をファイル名に持つ
computername =Year(NOW()) & _
Right("0" & Month(NOW()), 2) & _
Right("0" & Day(NOW()), 2) & _
Right("0" & Hour(NOW()), 2) & _
Right("0" & Minute(NOW()), 2) & _
Right("0" & Second(NOW()), 2)
'コンピュータ名取得
Set objNetwork = WScript.CreateObject("WScript.Network")
computername = objNetWork.ComputerName
'保存するためのファイルオブジェクト
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.CreateTextFile("d:\" & computername & ".txt", True)
'レジストリ操作オブジェクト
strComputer = "."
Set objRegProv = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
'レジストリからインストール情報取得
sytKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Call objRegProv.EnumKey(HKEY_LOCAL_MACHINE, sytKey, ccSubKeys)
For each strSubKey in ccSubKeys
dwVal = objRegProv.GetStringValue(HKEY_LOCAL_MACHINE, sytKey & "\" & strSubKey, "ParentKeyName", strParentKeyName)
If dwVal <> 0 Then ' ParentKeyNameが無いものが対象(更新インストールではないもの)
dwVal = objRegProv.GetDWORDValue(HKEY_LOCAL_MACHINE, sytKey & "\" & strSubKey, "SystemComponent", dwSystemComponent)
If dwVal <> 0 Or dwSystemComponent = 0 Then ' システムフラグが無いまたはゼロのものが対象
dwVal = objRegProv.GetStringValue(HKEY_LOCAL_MACHINE, sytKey & "\" & strSubKey, "DisplayName", strDisplayName)
If dwVal = 0 And strDisplayName <> "" Then ' 表示名があるものが対象
objTextFile.WriteLine strDisplayName
End If
End If
End If
Next
参考: