3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

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にあったサンプルです。

MS TechNet:インストール済みソフトウェアの列挙

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

参考:

猫科研究所(felid labo) - WSHのデバッガ