Question
How do I manually create a Custom Inventory NSI file?
Answer
Manually Creating a Custom Inventory NSI File
The information in this document is presented as-is and is not supported by Altiris.
This document describes how to manually or programmatically create an .NSI file for custom inventory and have it processed by the Notification Server. Frequently, Altiris customers will need to gather inventory data that is not accessible via standard Inventory Solution methods. In these cases, it is possible to create an NSI file from scratch using a programming or scripting language of the customer’s choice. The only requirement is to ensure that the .NSI file is formatted properly and that it contains valid information for processing by the inventory collector and subsequent processes.
Any data can be gathered in any manner desired and inserted into an NSI file. The NSI file must include an “InventoryClass” tag that specifies the database table name and an “AttributeType” tag for each column in the table. Each row of data to be inserted into the table will be specified within a “z:row” tag. The file must have an extension of ‘NSI’, upper or lower case. The sections from steps 2, 3 and 4 can be joined together to form a valid NSI file, as is.
This example will assume that a program will collect the desired data and loop through that data to insert it into the .NSI file. This example is for shortcut files and their targets and does not specify how to gather those shortcuts and targets.
<InventoryClasses>
<InventoryClass name='All Shortcuts' manufacturer='Altiris' description='' version='' platform='Win32' mifClass='Altiris|SHORTCUTS|1.0'>
<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly" rs:updatable="true">
<s:AttributeType name="c0" rs:name="shortcutFileName" rs:number="1" rs:keycolumn="true" mifAttrId='1'>
<s:datatype dt:type="string" dt:maxLength="255"/>
</s:AttributeType>
<s:AttributeType name="c1" rs:name="shortcutTarget" rs:number="2" rs:nullable="false" mifAttrId='2'>
<s:datatype dt:type="string" dt:maxLength="255"/>
</s:AttributeType>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row
c0="Windows Media Player.lnk"
c1="c:\Documents and Settings\somewhere\Microsoft\Internet Explorer\Quick Launch\"
/>
</rs:data>
</xml>
</InventoryClass>
</InventoryClasses>
<InventoryClass name='All Shortcuts' manufacturer='Altiris' description='' version='' platform='Win32' mifClass='Altiris|SHORTCUTS|1.0'>
<s:AttributeType name="c0" rs:name="shortcutFileName" rs:number="1" rs:keycolumn="true" mifAttrId='1'>
<s:datatype dt:type="string" dt:maxLength="255"/>
There must be an <s:AttributeType tag for each column to be added to the table. Column rs:number and mifattrid must increment sequentially with no gaps. The _id and _ResourceGuid columns are automatically added to the table. All other tags should be written as shown in this example or in the official Altiris documentation, including the values for the UUIDs.
<z:row c0="Windows Media Player.lnk" c1="c:\Documents and Settings\somewhere\Microsoft\Internet Explorer\Quick Launch\" />
Method 1: The NSI file can be written to the client PC’s C:\Program Files\Altiris\eXpress\Inventory Directory to be included in the next collector run, which creates an NSE file and sends it to the NS server.
Method 2: The NSI file can be written to a temporary directory on the client PC created specifically for this data-gathering purpose. This will allow the collector to be run immediately to have an NSE file created from just this NSI file (and any others in that temp directory) and sent to the NS server. In this case, the collector command-line must specify the source directory with a ‘/s’ parameter, i.e., "aexnsinvcollector.exe /s C:\custinv...".
After processing on the server has completed, the data will show in the NS Console Resource Manager, Inventory tab, “Default” folder.
const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\"&_
strComputer & "\root\default:StdRegProv")
' strKeyPath is the path in the registry from hkey_local_machine.
' Presumably, the const variable could be removed and the entire path entered here
' strValueName is the registry key name from which values will be retrieved
' strClassName is the inventoryclass name, which becomes the dataclass or database table
' name that will be created/used in NS. The dataclass must be unique for each set of
' data to be collected. The dataloader drops the data from the existing dataclass
' prior to loading the most recent data. It's not cummulative (it does not append).
' It is helplful to begin the class name with a common string to group them in
' the database and in resource manager.
' strFileName is the nsi file name.
'strKeyPath = "SYSTEM\CurrentControlSet\Services\Eventlog\System"
'strValueName = "Sources"
'strClassName = "RegEventLogSources"
'strFileName = strClassName + ".nsi"
' There are two sets here just to make it easy to switch.
strKeyPath = "SOFTWARE\Microsoft\MSSQLServer\Client\SuperSocketNetLib"
strValueName = "ProtocolOrder"
strClassName = "RegProtocolOrder"
strFileName = strClassName + ".nsi"
' Write out beginning information on the dataclass to build the nsi
' The attributes may need to be modified depending on the data to be collected.
' See knowledge base article AKB6866 for details on what to change
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(strFileName, 2, True)
'objTextFile.WriteLine("serverName")
objTextFile.WriteLine("<InventoryClasses>")
objTextFile.WriteLine(" <InventoryClass name='" + strClassName + "' manufacturer='Altiris' description='' version='' platform='Win32' mifClass='Altiris|SHORTCUTS|1.0'>")
objTextFile.WriteLine(" <xml xmlns:s=""uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"" xmlns:dt=""uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"" xmlns:rs=""urn:schemas-microsoft-com:rowset"" xmlns:z=""#RowsetSchema"">")
objTextFile.WriteLine(" <s:Schema id=""RowsetSchema"">")
objTextFile.WriteLine(" <s:ElementType name=""row"" content=""eltOnly"" rs:updatable=""true"">")
objTextFile.WriteLine(" <s:AttributeType name=""c0"" rs:name=""RegKeyPath"" rs:number=""1"" rs:keycolumn=""true"" mifAttrId='1'>")
objTextFile.WriteLine(" <s:datatype dt:type=""string"" dt:maxLength=""255""/>")
objTextFile.WriteLine(" </s:AttributeType>")
objTextFile.WriteLine(" <s:AttributeType name=""c1"" rs:name=""RegKey"" rs:number=""2"" rs:keycolumn=""true"" mifAttrId='2'>")
objTextFile.WriteLine(" <s:datatype dt:type=""string"" dt:maxLength=""255""/>")
objTextFile.WriteLine(" </s:AttributeType>")
objTextFile.WriteLine(" <s:AttributeType name=""c2"" rs:name=""Multi_Reg_SZValue"" rs:number=""3"" rs:keycolumn=""true"" mifAttrId='3'>")
objTextFile.WriteLine(" <s:datatype dt:type=""string"" dt:maxLength=""255""/>")
objTextFile.WriteLine(" </s:AttributeType>")
objTextFile.WriteLine(" </s:ElementType>")
objTextFile.WriteLine(" </s:Schema>")
objTextFile.WriteLine(" <rs:data>")
' Perform the call to get the registry data
Return = objReg.GetMultiStringValue(HKEY_LOCAL_MACHINE,strKeyPath,_
strValueName,arrValues)
If (Return = 0) And (Err.Number = 0) Then
' Write out the data elements to the nsi file
For Each strValue In arrValues
OutString = " <z:row" _
& " c0=""" + strKeyPath + """" _
& " c1=""" + strValueName + """" _
& " c2=""" + strValue + """" _
& "/>"
objTextFile.WriteLine(Outstring)
Next
' add closing tags to the nsi file
objTextFile.WriteLine(" </rs:data>")
objTextFile.WriteLine(" </xml>")
objTextFile.WriteLine(" </InventoryClass>")
objTextFile.WriteLine("</InventoryClasses>")
objTextFile.close
Else
Wscript.Echo "GetMultiStringValue failed. Error = " & Err.Number
End If