Win32OLEでインストール済みソフトウェア一覧を取得してみたよ
リーマンは時折無駄としか思えない人力作業を強制させられるときがあります。インベントリを人力で調べるなんて拷問ですよ。
ささっとvbsを書いて終わりのつもりだったのですが妙に遅い...半端ではない遅さ。
hostname = "remote_host" set locator = CreateObject("WbemScripting.SWbemLocator") Set wmi = locator.ConnectServer(hostname, "ROOT\cimv2", "user", "password") Set items = wmi.ExecQuery("Select * from Win32_Product",,48) For Each item in items Wscript.Echo "Caption: " & item.Caption Wscript.Echo "Version: " & item.Version Next
どうやら win32_productクラスがよくないようです。「win32_product slow」とググるとワンサカ出てきます。MSI経由で情報を取得するため、超がつくほど遅いようです。
インストール済みアプリケーションの情報取得はレジストリ経由の方が速そう。ただx86とx64のアプリケーションは別のレジストリで管理しているので注意が必要です。
require 'win32ole' require 'socket' module REG arch = ENV["PROCESSOR_ARCHITECTURE"] == "AMD64" ? x64 : "x86" UNINSTALLS = if arch == "x64" [ "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\uninstall", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\uninstall", ] else [ "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\uninstall", ] end HKEY_CLASSES_ROOT = 0x80000000 HKCR = 0x80000000 HKEY_CURRENT_USER = 0x80000001 HKCU = 0x80000001 HKEY_LOCAL_MACHINE = 0x80000002 HKLM = 0x80000002 HKEY_USERS = 0x80000003 HKEY_CURRENT_CONFIG = 0x80000005 HKEY_DYN_DATA = 0x80000006 end include REG # File activesupport/lib/active_support/core_ext/hash/keys.rb class Hash def symbolize_keys! keys.each do |key| self[(key.to_sym rescue key) || key] = delete(key) end self end end class Software def initialize(hostname = ".", opt = {}) wmi = conn_server(hostname, opt) @reg = wmi.Get("StdRegProv") end def conn_server(hostname, opt) locator = WIN32OLE.new("WbemScripting.SWbemLocator") if Socket.gethostname == hostname || "." == hostname locator.ConnectServer("." ,"root\\default") else locator.ConnectServer(hostname ,"root\\default", opt[:user], opt[:pass]) end end def each_subkey in_param = @reg.Methods_("EnumKey").InParameters.SpawnInstance_() in_param.hDefKey = REG::HKLM REG::UNINSTALLS.each {|key| in_param.sSubKeyName = key out_param = @reg.ExecMethod_("EnumKey", in_param) out_param.sNames.each {|subkey| yield key + "\\" + subkey } } end def each_products in_param = @reg.Methods_("GetStringValue").InParameters.SpawnInstance_() in_param.hDefKey = REG::HKLM self.each_subkey {|key| product = {} in_param.sSubKeyName = key %w(DisplayVersion DisplayName).each {|label| in_param.sValueName = label out_param = @reg.ExecMethod_("GetStringValue",in_param) product[label] = out_param.sValue.to_s } yield product.symbolize_keys! } end end
こういうのはWin32OLEで書くほうが楽しいです。こんなかんじで実行すればOK.
so = Software.new so.each_products {|h| next if h[:DisplayName].empty? p h }