Video Screencast Help

How to Programmatically Create a Custom Inventory NSI File

Created: 11 Jul 2006 • Updated: 07 Jun 2007
Language Translations
dougj's picture
0 0 Votes
Login to vote

This document describes how to manually or programmatically create an NSI file for custom inventory and have it processed by the Notification Server.

Disclaimer

The information in this document is presented as-is and is not supported by Altiris.

Overview

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. For further details on the layout of an NSI file, please see http://www.altiris.com/support/documentation. 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.

Example Logic and NSI File

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.

  1. Start program or script and gather the desired data. Store it temporarily in an array, database, text file or wherever.
  2. Write the following static text that defines the table and column schema (make modifications to this text as described below):
  3. <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>
    
    
  4. Loop through the data and create a <z:row tag with the c0, c1… elements as described in the schema above:
  5. <z:row
       c0="Windows Media Player.lnk"
       c1="c:\Documents and Settings\somewhere\Microsoft\Internet Explorer\Quick Launch\"
    />
    
    
  6. When all data has been added to the NSI file, write the closing tags:
  7.             </rs:data>
            </xml>
        </InventoryClass>
    </InventoryClasses>
    
    
  8. Write the file to the desired location depending on how it will be collected.

Tag elements that can be modified

<InventoryClass name='All Shortcuts' manufacturer='Altiris' description='' version='' platform='Win32' mifClass='Altiris|SHORTCUTS|1.0'>

  • "name" is the name of the database table. It will be preceded with "inv_" and any spaces will be replaced with an underscore (_).
  • "manufacturer" can be anything of your choosing, even determined programmatically.
  • "description" can be anything of your choosing, even determined programmatically.
  • "version" can be anything of your choosing, even determined programmatically.
  • "platform" can be anything of your choosing, even determined programmatically.
  • "mifClass" must contain three segments separated by a pipe symbol (|). It is recommended that the first segment be '"Altiris". This will fail SMS processing if it contains spaces.

<s:AttributeType name="c0" rs:name="shortcutFileName" rs:number="1" rs:keycolumn="true" mifAttrId='1'>
<s:datatype dt:type="string" dt:maxLength="255"/>

 

  • "name" is the column number of this data element, beginning at zero. There can be no gaps in numbering.
  • "rs:name" is the name of the column in the database table. (Remember, that it's difficult, if not impossible, to change table and column names for a given class once they have been created in the database, so choose names you'll want to live with for a long time.)
  • "rs:number" is the column number, beginning at one. There can be no gaps in numbering.
  • "rs:keycolumn" specifies if this column is a key in the database table. It is optional. Other possible elements include "rs:nullable", as shown in the example above. Please see the documentation for further details.
  • "mifAttrId" must correspond to "rs:number".
  • "s:datatype" can be one of the following: string, int or datetime.
  • "dt:maxLength" is the length of the column in the database. The maximum length of any column specified in an NSI file is 255 characters.

There must be an <s:AttributeType tag for each column to be added to the table. Column numbers 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\" />

  • "c0", "c1"… correspond to the AttributeTypes specified in the schema in step #2, above. The element and the data must match the schema or the data insertion may fail or the data will be corrupt. The data is free-form according to the schema specification in step #2 and the database datatype requirements.

File Output

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.

Sample VBScript

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("")
objTextFile.WriteLine("  ")
objTextFile.WriteLine("    ")
objTextFile.WriteLine("      ")
objTextFile.WriteLine("        ")
objTextFile.WriteLine("          ")
objTextFile.WriteLine("            ")
objTextFile.WriteLine("          ")
objTextFile.WriteLine("          ")
objTextFile.WriteLine("            ")
objTextFile.WriteLine("          ")
objTextFile.WriteLine("          ")
objTextFile.WriteLine("            ")
objTextFile.WriteLine("          ")
objTextFile.WriteLine("        ")
objTextFile.WriteLine("      ")
objTextFile.WriteLine("      ")

' 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 = "        "
		objTextFile.WriteLine(Outstring)
	Next

' add closing tags to the nsi file		
	objTextFile.WriteLine("      ")
   objTextFile.WriteLine("    ")
   objTextFile.WriteLine("  ")
   objTextFile.WriteLine("")
	objTextFile.close
	
Else
    Wscript.Echo "GetMultiStringValue failed. Error = " & Err.Number
End If