Video Screencast Help
Protect Your POS Environment Against Retail Data Breaches. Learn More.

NS7.1 Custom inventory help - registry values

Created: 16 Mar 2013 • Updated: 06 Jun 2013 | 6 comments
This issue has been solved. See solution.

Hi folks,

I need some help with a custom inventory of a registry key. I have scoured the forums here, and found many helpful articles, which have gotten me as far as I have. I have created a custom dataclass and modified the sample Windows custom inventory script for registry data - all of this was a lot simpler than I expected it to be. However, something isn't working, so obviously I've done something wrong. After running my custom inventory on a client, my dataclass is still empty.

What I am trying to do: I am attempting to query ONE registry key: “HKLM\SOFTWARE\Nico Mak Computing\WinZip\WinIni" to grab 7 registry values. Later, we will create a filter based upon these values in order to set up an Application Metering policy to block unlicensed copies of Winzip. Can anyone identify what I am doing wrong?

Here is an example of the Winzip "Winini" registry key I am trying to grab data from. This computer only has 2 of the 7 registry values I want to grab. As you can see, this will be a pretty simple registry inventory. No multiple keys, just multiple values within the same registry key.

 

So, based on that registry key, I made the following data class:

 

Lastly, there is my script:

'Gather registry key value from machine and posting data to NS using Altiris NSE Component
'===================================================================================================================
'      On Error Resume Next

const HKEY_LOCAL_MACHINE = &H80000002

strComputer = "."
Set oReg=GetObject( _
   "winmgmts:{impersonationLevel=impersonate}!\\" &_
    strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Nico Mak Computing\WinZip\WinIni"
strValueName1 = "Setup"
strValueName2 = "win32_version"
strValueName3 = "Name"
strValueName4 = "SN"
strValueName5 = "UZQF"
StrValueName6 = "Name1"
StrValueName7 = "SN1"
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName1,Setup
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName2,win32_version
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName3,Name
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName4,SN
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName5,UZQF
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName6,Name1
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName7,SN1

if isnull(Setup) then
  Setup = "missing"
end if

if isnull(win32_version) then
  win32_version = "missing"
end if

if isnull(Name) then
  Name = "missing"
end if

if isnull(SN) then
  SN = "missing"
end if

if isnull(UZQF) then
  UZQF = "missing"
end if

if isnull(Name1) then
  SN = "missing"
end if

if isnull(SN) then
  SN = "missing"
end if

 

'===================================================================================================================

'Create instance of Altiris NSE component
dim nse
set nse = WScript.CreateObject ("Altiris.AeXNSEvent")

' Set the header data of the NSE
' Please don't modify this GUID
nse.To = "{1592B913-72F3-4C36-91D2-D4EDA21D2F96}"
nse.Priority = 1

'Create Inventory data block. Here assumption is that the data class with below guid is already configured on server
dim objDCInstance
'Insert custom Data Class GUID here
set objDCInstance = nse.AddDataClass ("{6741a63d-8c48-428d-a7c0-54e3421e60f0 }")

dim objDataClass
set objDataClass = nse.AddDataBlock (objDCInstance)

'Add a new row
dim objDataRow
set objDataRow = objDataClass.AddRow
'Set columns
objDataRow.SetField 0, Setup
objDataRow.SetField 1, win32_version
objDataRow.SetField 2, Name
objDataRow.SetField 3, UZQF
objDataRow.SetField 3, SN
objDataRow.SetField 3, Name1
objDataRow.SetField 3, SN

nse.SendQueued

 

So, that's everything. Should be pretty simple, right? I have a feeling someone is going to point out one really obvious thing that I did wrong, and once corrected, everything should work. Well, I'm hoping at any rate...

Any help would be appreciated! Thank you,

Dustin

 

Operating Systems:

Comments 6 CommentsJump to latest comment

The Gaffer's picture

I imagine that you have already spotted the really obvious thing wrong with your script, but in case you haven't:

objDataRow.SetField 0, Setup
objDataRow.SetField 1, win32_version
objDataRow.SetField 2, Name
objDataRow.SetField 3, UZQF
objDataRow.SetField 3, SN
objDataRow.SetField 3, Name1
objDataRow.SetField 3, SN

SOLUTION
DustinW's picture

Yep, that was about as obvious as it gets, and thanks, I did miss it. Still, dataclass is empty. Any other pointers?

kh@syscomworld.com's picture

 

Hi,
I assume that the GUID is correct GUID of the Custom data class.
I tested the script, and it failed. Name1 and SN1 should be corrected.

 

'Gather registry key value from machine and posting data to NS using Altiris NSE Component
'===================================================================================================================
'      On Error Resume Next
 
const HKEY_LOCAL_MACHINE = &H80000002
 
strComputer = "."
Set oReg=GetObject( _
   "winmgmts:{impersonationLevel=impersonate}!\\" &_
    strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Nico Mak Computing\WinZip\WinIni"
strValueName1 = "Setup"
strValueName2 = "win32_version"
strValueName3 = "Name"
strValueName4 = "SN"
strValueName5 = "UZQF"
StrValueName6 = "Name1"
StrValueName7 = "SN1"
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName1,Setup
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName2,win32_version
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName3,Name
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName4,SN
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName5,UZQF
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName6,Name1
oReg.GetStringValue _
   HKEY_LOCAL_MACHINE,strKeyPath,strValueName7,SN1
 
if isnull(Setup) then
  Setup = "missing"
end if
 
if isnull(win32_version) then
  win32_version = "missing"
end if
 
if isnull(Name) then
  Name = "missing"
end if
 
if isnull(SN) then
  SN = "missing"
end if
 
if isnull(UZQF) then
  UZQF = "missing"
end if
 
if isnull(Name1) then
  Name1 = "missing"
end if
 
if isnull(SN1) then
  SN1 = "missing"
end if
 
 
'===================================================================================================================
 
'Create instance of Altiris NSE component
dim nse
set nse = WScript.CreateObject ("Altiris.AeXNSEvent")
 
' Set the header data of the NSE
' Please don't modify this GUID
nse.To = "{1592B913-72F3-4C36-91D2-D4EDA21D2F96}"
nse.Priority = 1
 
'Create Inventory data block. Here assumption is that the data class with below guid is already configured on server
dim objDCInstance
'Insert custom Data Class GUID here
set objDCInstance = nse.AddDataClass ("{6741a63d-8c48-428d-a7c0-54e3421e60f0 }")
 
dim objDataClass
set objDataClass = nse.AddDataBlock (objDCInstance)
 
'Add a new row
dim objDataRow
set objDataRow = objDataClass.AddRow
'Set columns
objDataRow.SetField 0, Setup
objDataRow.SetField 1, win32_version
objDataRow.SetField 2, Name
objDataRow.SetField 3, UZQF
objDataRow.SetField 4, SN
objDataRow.SetField 5, Name1
objDataRow.SetField 6, SN1
 
nse.SendQueued

 

AngelD's picture

You could just specify the (exact) name of the custom inventory instead, instead of the GUID.

'Insert custom Data Class GUID here
set objDCInstance = nse.AddDataClass ("MyCustomInventory")

 

Execute the script locally on the client and then check if the (custom inventory) table has been populated with that client's inventory data

 

AngelD's picture

Just had some free time to give you this;

change CUSTOM_INVENTORY_NAME_OR_GUID to your actuall custom inventory name or guid.

Option Explicit
'//  Desc: The data class WinZip_License_Inventory stores information WinZip licenses
'//  DataClass.Field 0 = Setup
'//  DataClass.Field 1 = win32_version
'//  DataClass.Field 2 = Name
'//  DataClass.Field 3 = SN
'//  DataClass.Field 4 = UZQF
'//  DataClass.Field 5 = Name1
'//  DataClass.Field 6 = SN1
'////////////////////////////////////////////////////////////

Const CUSTOM_INVENTORY_NAME_OR_GUID = "WinZip_License_Inventory"

Const REG_KEY = "HKEY_LOCAL_MACHINE\SOFTWARE\Nico Mak Computing\WinZip\WinIni"
Const REG_ENTRIES = "Setup,win32_version,Name,SN,UZQF,Name1,SN1"

Dim value
Dim oNSEvent, oDataBlock

'// WinZip not installed; no need to send inventory data
'// (default registry entry does not exist)
If (not GetRegistryEntry(REG_KEY, "", value)) Then wscript.quit(0)

Set oDataBlock = NSE_CreateCustomInvDataBlock(CUSTOM_INVENTORY_NAME_OR_GUID, oNSEvent)

'// failed to add inventory data
if (not AddInventoryData(oDataBlock)) then wscript.quit(1)

'// Send inventory data
oNSEvent.SendQueued

Function AddInventoryData(ByRef oNSEDataBlock)
	On Error Resume Next
	Dim oDataRow, values, i, value
	AddInventoryData = false

	err.clear
	Set oDataRow = oNSEDataBlock.AddRow
	If (Err <> 0) Then Exit Function

	values = split(REG_ENTRIES, ",")
	for i = 0 to ubound(values)
		If (not GetRegistryEntry(REG_KEY, values(i), value)) Then
			value = "missing"
		end if

		oDataRow.SetField i, ToXmlString(value)
		If (Err <> 0) Then Exit Function
	next

	AddInventoryData = true
End Function

Function NSE_CreateCustomInvDataBlock(ByVal sCustomInvName, ByRef oNSEvent)
	On Error Resume Next
	Dim oDataClass
	
	Set NSE_CreateCustomInvDataBlock = Nothing
	Set oNSEvent = Nothing
	
	Err.Clear
	Set oNSEvent = CreateObject("Altiris.AeXNSEvent")
	If (Err <> 0) Then Exit Function

	' Set the header data of the NSE (don't modify this GUID)
	oNSEvent.To = "{1592B913-72F3-4C36-91D2-D4EDA21D2F96}"	'// Basic Inventory Capture Item (Inventory Capture Item)
	oNSEvent.Priority = 1

	Set oDataClass = oNSEvent.AddDataClass(sCustomInvName)
	If (Err <> 0) Then Exit Function
	Set NSE_CreateCustomInvDataBlock = oNSEvent.AddDataBlock(oDataClass)
	If (Err <> 0) Then Exit Function
End Function

Function ToXmlString(value)
	Dim sXmlString
	
	If (IsNull(value)) Then
		sXmlString = value
	Else
		sXmlString = value
		sXmlString = Replace(sXmlString, "&", "&")
		sXmlString = Replace(sXmlString, """", """)
		sXmlString = Replace(sXmlString, "<", "<")
		sXmlString = Replace(sXmlString, ">", ">")
	End If
	
	ToXMLString = sXmlString
End Function

Function GetRegistryEntry(sRegPath, sEntryName, value)
	on error resume next
	dim oWshShell, regpath
	GetRegistryEntry = false
	
	regpath = sRegPath
	If (Right(regpath, 1) <> "\") Then regpath = regpath & "\"
	regpath = regpath & sEntryName
	
	Set oWshShell = CreateObject("WScript.Shell")
	
	Err.Clear
	value = oWshShell.RegRead(regpath)
	If (Err = 0) Then GetRegistryEntry = true
	Err.Clear
	
	Set oWshShell = Nothing
End Function

AngelD's picture

I think I see why you're having problem with your empty dataclass,

set objDCInstance = nse.AddDataClass ("{6741a63d-8c48-428d-a7c0-54e3421e60f0 }")

remove the space at the end, your guid should look like: "{6741a63d-8c48-428d-a7c0-54e3421e60f0}"

 

SOLUTION