Module: check_mk
Branch: master
Commit: 46b5b69a1561b744ddc339d558ab6784777963e9
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=46b5b69a1561b7…
Author: Sven Rueß <sr(a)mathias-kettner.de>
Date: Thu Mar 2 16:28:14 2017 +0100
4385 FIX mk_inventory.vbs: Add new query type for installed software on hosts
We added a new query type to get the information about installed software on hosts.
This new type is the default way, how information is collected.
The old way is a fallback and will be tried, if the new one is not possible.
In error situations, we do not query the installed software and report an empty section.
Change-Id: I691974af4abfd8af97685d7e4e63658dd8c4efe2
---
.werks/4385 | 15 ++++
agents/windows/plugins/mk_inventory.vbs | 122 ++++++++++++++++++++++----------
2 files changed, 100 insertions(+), 37 deletions(-)
diff --git a/.werks/4385 b/.werks/4385
new file mode 100644
index 0000000..47b2da9
--- /dev/null
+++ b/.werks/4385
@@ -0,0 +1,15 @@
+Title: mk_inventory.vbs: Add new query type for installed software on hosts
+Level: 1
+Component: inv
+Class: fix
+Compatible: compat
+Edition: cre
+State: unknown
+Version: 1.5.0i1
+Date: 1488465519
+
+We added a new query type to get the information about installed software on hosts.
+This new type is the default way, how information is collected.
+The old way is a fallback and will be tried, if the new one is not possible.
+
+In error situations, we do not query the installed software and report an empty section.
diff --git a/agents/windows/plugins/mk_inventory.vbs
b/agents/windows/plugins/mk_inventory.vbs
index d11163c..c0b2ee7 100644
--- a/agents/windows/plugins/mk_inventory.vbs
+++ b/agents/windows/plugins/mk_inventory.vbs
@@ -1,24 +1,31 @@
+' Check, if we are executed with cscript.exe
+If UCase(Right(Wscript.FullName, 11)) = "WSCRIPT.EXE" Then
+ WScript.Echo "This script must be run under CScript."
+ Wscript.Quit
+End If
+
CONST HKLM = &H80000002
Dim delay
Dim exePaths
Dim regPaths
-' these three lines are set in the agent bakery
+' These three lines are set in the agent bakery
delay = 14400
exePaths = Array("")
regPaths =
Array("Software\Microsoft\Windows\CurrentVersion\Uninstall","Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall")
Set fso = CreateObject("Scripting.FileSystemObject")
-' request unicode stdout and add a bom so the agent knows we send utf-16
+' Request unicode stdout and add a bom so the agent knows we send utf-16
Set objStdout = fso.GetStandardStream(1, True)
objStdout.Write(chrW(&HFEFF))
Set objClass =
GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set wshShell = WScript.CreateObject( "WScript.Shell" )
remote_host = wshShell.ExpandEnvironmentStrings( "%REMOTE_HOST%" )
If remote_host = "%REMOTE_HOST%" Then
- remote_host = "local"
+ remote_host = "local"
End If
+
state_dir = wshShell.ExpandEnvironmentStrings( "%MK_STATEDIR%" )
conf_dir = wshShell.ExpandEnvironmentStrings( "%MK_CONFDIR%" )
@@ -27,64 +34,64 @@ If state_dir = "%MK_STATEDIR%" Then
state_dir = conf_dir
End If
-' to be able to quickly change the output function
+' Output definition, to be quickly able to change the output function
Sub outPut(strOut)
- 'WScript.Echo strOut
+ ' WScript.Echo strOut
objStdout.WriteLine strOut
End Sub
timestamp = state_dir & "\mk_inventory." & Replace(remote_host,
":", "_")
-' does timestamp exist?
+' Does timestamp exist?
If (fso.FileExists(timestamp)) Then
Set objTimestamp = fso.GetFile(timestamp)
fileDate = objTimestamp.DateLastModified
- ' exit if timestamp is too young
+
+ ' Exit if timestamp is too young
If DateAdd("s", delay, filedate) >= Now Then
WScript.Quit
End If
End If
-
-' handle error message ourselves so this script can also be run directly, for
testing
+' Handle error message ourselves so this script can also be run directly, for
testing
On Error Resume Next
-
-' create new timestamp file
-' only allowed when script runs as administrator user
+' Create new timestamp file
+' Only allowed when script runs as administrator user
Set stampo = fso.CreateTextFile(timestamp)
If Err.Number <> 0 Then
- outPut "Failed to create time stamp: " & Err.Description & "
(" & Err.Number & ")"
+ outPut "Failed to create time stamp: " & Err.Description & "
(" & Err.Number & ")"
Err.Clear
End If
On Error Goto 0
-
-' determine the timezone offset w/t GMT
+' Determine the timezone offset w/t GMT
Set systemParams = objClass.ExecQuery("Select * from Win32_ComputerSystem")
For Each param in systemParams
offset = param.CurrentTimeZone
Exit For
Next
-' the unix timestamp
+' The unix timestamp
epoch = DateDiff("s", "01/01/1970 00:00:00", Now()) - (offset * 60)
-' convert add delay seconds plus 5 minutes
+' Convert add delay seconds plus 5 minutes
timeUntil = epoch + delay + 300
+
Sub startSection(name,sep,timeUntil)
outPut("<<<" & name & ":sep(" & sep &
"):persist(" & timeUntil & ")>>>")
End Sub
+
Sub getWMIObject(strClass,arrVars)
Set objClass =
GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set Entries = objClass.ExecQuery("Select * from " & strClass)
For Each entry in Entries
For Each item in entry.Properties_
- ' if it is in arrVars
+ ' If it is in arrVars
If UBound(filter(arrVars, item.name)) = 0 Then
If isArray(item.value) Then
outPut(item.name & ": " & join(item.value))
@@ -96,6 +103,7 @@ Sub getWMIObject(strClass,arrVars)
Next
End Sub
+
Sub getWMIObject2(strClass,arrVars)
Set Entries = objClass.ExecQuery("Select * from " & strClass)
For Each entry in Entries
@@ -112,15 +120,15 @@ Sub getWMIObject2(strClass,arrVars)
Next
End Sub
+
Sub RecurseForExecs(strFolderPath)
- Dim objFolder
- Set objFolder = fso.GetFolder(strFolderPath)
+ Dim objFolder : Set objFolder = fso.GetFolder(strFolderPath)
Dim objFile
Dim objSubFolder
For Each objFile In objFolder.Files
- 'only proceed if there is an extension on the file.
+ ' Only proceed if there is an extension on the file.
If (InStr(objFile.Name, ".") > 0) Then
- 'If the file's extension is "exe", write the path to the
output file.
+ ' If the file's extension is "exe", write the path to the
output file.
If (LCase(Mid(objFile.Name, InStrRev(objFile.Name, "."))) =
".exe") Then
outPut(objFile.Path & "|" & objFile.DateLastModified
& "|" & objFile.Size & "|" & "" &
"|" & fso.GetFileVersion(objFile.path) & "|")
End If
@@ -132,22 +140,62 @@ Sub RecurseForExecs(strFolderPath)
Next
End Sub
+
Sub SoftwareFromInstaller(fields)
- Dim installer
- Set installer = CreateObject("WindowsInstaller.Installer")
- Dim productCode, productName
- For Each productCode In installer.Products
- values = fields ' copy
- idx = 0
-
- For Each field In fields
- values(idx) = installer.ProductInfo(productCode, field)
- idx = idx + 1
- Next
- outPut(Join(values, "|"))
+ const WI_SID_EVERYONE = "s-1-1-0"
+ const WI_ALL_CONTEXTS = 7
+
+ Dim oInstaller : Set oInstaller =
CreateObject("WindowsInstaller.Installer")
+ Dim oProducts : Set oProducts = oInstaller.ProductsEx("", WI_SID_EVERYONE,
WI_ALL_CONTEXTS)
+ Dim productsEx
+
+ if Err.Number = 0 Then
+ productsEx = true
+ else
+ productsEx = false
+ oProducts = oInstaller.Products
+ if Err.Number <> 0 Then
+ ' Exit here, because we are unable to query the installed software
+ ' outPut("Can not list installed software")
+ Exit Sub
+ End If
+ End If
+
+ Dim IteratedItem, productCode
+ For Each IteratedItem In oProducts
+ On Error Resume Next
+ if productsEx then
+ ' ProductEx function
+ Err.clear()
+ Dim oProduct : Set oProduct = IteratedItem
+ productCode = oProduct.ProductCode
+ values = fields ' copy
+ idx = 0
+
+ For Each field In fields
+ values(idx) = oProduct.InstallProperty(field)
+ idx = idx + 1
+ Next
+
+ outPut(Join(values, "|"))
+ else
+ 'Products function
+ Err.clear()
+ productCode = IteratedItem
+ values = fields ' copy
+ idx = 0
+
+ For Each field In fields
+ values(idx) = oInstaller.ProductInfo(productCode, field)
+ idx = idx + 1
+ Next
+
+ outPut(Join(values, "|"))
+ end if
Next
End Sub
+
' Processor
Call startSection("win_cpuinfo",58,timeUntil)
cpuVars = Array(
"Name","Manufacturer","Caption","DeviceID","MaxClockSpeed","AddressWidth","L2CacheSize","L3CacheSize","Architecture","NumberOfCores","NumberOfLogicalProcessors","CurrentVoltage","Status"
)
@@ -199,7 +247,7 @@ For Each path in regPaths
boleanContent = False
For Each var in regVars
' PSChildName is the name in powershell
- ' we use strIdentityCode in vbs
+ ' We use strIdentityCode in vbs
If var = "PSChildName" Then
value = strIdentityCode
' Language is a DWord
@@ -209,10 +257,10 @@ For Each path in regPaths
Else
intResult = rego.GetStringValue(HKLM, path & "\" &
strIdentityCode, var, value)
End If
- ' only allow vartypes which can be represented as a string
+ ' Only allow vartypes which can be represented as a string
If VarType(value) <= 8 and VarType(value) > 1 Then
strOut = strOut & "|" & CStr(value)
- ' only print a line when more than only PSChildName is present
+ ' Only print a line when more than only PSChildName is present
If var <> "PSChildName" Then
boleanContent = True
End If