Monday, September 24, 2012

HP Warranty Information in the SCCM Hardware Inventory -( Worth Reading )


This process is dependent on the output from an HP web site.  If HP updates the format of the output from the site, it could affect the processing of the data.  also, this configuration assumes that the script running under system credentials as an SCCM program has access to the HP site.  If proxy or any other type of credentials are required for internet access, this process may not work without modifications for the environment.
The script is below.  You will want to change the ComapnyName reference to your company name.  This value will be used later as well.
EnableLogging = True

sCompanyName = "CompanyName"

Set oShell = CreateObject("wscript.Shell")
Set fso = CreateObject("scripting.filesystemobject")

If EnableLoggingThen
    Set oLogFile = fso.OpenTextFile("C:\Windows\Temp\WarrantyInfo.log", 8, True)
    oLogFile.WriteLine"*********************************************************"
EndIf

WriteLog"Beginning warranty information lookup."

sWebServiceHost = "http://h20000.www2.hp.com/bizsupport/TechSupport"
sWebServiceURL = "WarrantyResults.jsp"
sWebService = sWebServiceHost & "/" & sWebServiceURL

'Get the system's serial number from WMI
Set oWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = oWMIService.ExecQuery("Select SerialNumber from Win32_BIOS",,48)
ForEach objItemin colItems
    sSerialNumber = objItem.SerialNumber
Next

WriteLog"Serial number of system is " & sSerialNumber

'Get the Product ID from WMI
Const wbemFlagReturnImmediately = 16
Const wbemFlagForwardOnly = 32
lFlags = wbemFlagReturnImmediately + wbemFlagForwardOnly
strService = "winmgmts:{impersonationlevel=impersonate}//./root/HP/InstrumentedBIOS"
strQuery = "select * from HP_BIOSSetting"
Set objWMIService = GetObject(strService)
Set colItems = objWMIService.ExecQuery(strQuery,,lFlags)
sProductNumber = ""
ForEach objItemIn colItems
    If objItem.Name = "SKU Number"Then
        sProductNumber = objItem.Value
    EndIf
    If objItem.Name = "Product Number"Then
        sProductNumber = objItem.Value
    EndIf
Next

IfLen(sProductNumber) = 0Then
    WriteLog"ERROR: Product Number could not be determined."
    oLogFile.WriteLine"*********************************************************"
    oLogFile.Close
    WScript.Quit(9)
Else
    WriteLog"Product number of the system is " & sProductNumber
EndIf

Set colItems = oWMIService.ExecQuery("Select AddressWidth from Win32_Processor",,48)
ForEach objItemin colItems
    sAddressWidth = objItem.AddressWidth
Next

WriteLog"Operating system is " & sAddressWidth & " bit."

'Define the parameters string to send to the web site
sParameters = "nickname=&sn=" & sSerialNumber & "&country=US&lang=en&cc=us&pn=" & sProductNumber & "&find=Display+Warranty+Information+%C2%BB&"

WriteLog"Opening the web site URL " & sWebService & "?" & sParameters

'Define and call the web site
Set oHTTP = CreateObject("Microsoft.xmlhttp")
oHTTP.open"GET", sWebService & "?" & sParameters, False
'oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oHTTP.send

If oHTTP.Status = 200Then
    WriteLog"Successful response from the web site."
    'WriteLog oHTTP.ResponseText
    Process oHTTP.ResponseText
Else
    WriteLog"ERROR: the web site returned status code " & oHTTP.Status
    WriteLog"Returning exit code 1."
    nExitCode = 1
EndIf

If EnableLoggingThen
    oLogFile.WriteLine"*********************************************************"
    oLogFile.Close
EndIf

WScript.Quit (nExitCode)

Function Process (HTML)
    WriteLog"Processing the HTML returned from the site."
    
    intSummaryPos = InStr(LCase(html), "serial number")
    
    If intSummaryPos = 0Then
        Process = ""
        ExitFunction
    EndIf
    
    intSummaryTable1Start = InStrRev(LCase(html), "<table", intSummaryPos)
    intSummaryTable1End = InStr(intSummaryPos, LCase(html), "</table>") + 8
    intSummaryTable2Start = InStr(intSummaryTable1End, LCase(html), "<table")
    intSummaryTable2End = InStr(intSummaryTable2Start, LCase(html), "</table>")
    
    table1 = getStr(intSummaryTable1Start, intSummaryTable1End, html)
    table2 = getStr(intSummaryTable2Start, intSummaryTable2End, html)
    
    const HKLM = &H80000002
    Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

    sKeyPath = "SOFTWARE\" & sCompanyName & " \WarrantyInformation"
    
    WriteLog"Registry key path is HKLM\" & sKeyPath
    
    oReg.CreateKey HKLM,sKeyPath

    WriteLog"Processing the first table from the web  page."
    arrGeneral = processTables(table1,1)   
    'arrGeneal should be in the form Serial Number, Product Number, Product Line, Product Description, Warranty Check Date
    
    WriteLog"Processing the second table from the web  page."    
    arrContracts = processTables(table2,2)
    'arrContracts should be in the format Warranty Type, HW Warrenty Start Date, HW Warranty End Date, HW Warranty Status, Setup Warranty Start Date, Setup Warranty End Date, Setup Warranty Status
    WriteLog"Setting registry values."
    WriteLog"SerialNumber is " & arrGeneral(0)
    oReg.SetStringValue HKLM, sKeyPath, "SerialNumber", arrGeneral(0)
    WriteLog"ProductNumber is " & arrGeneral(1)
    oReg.SetStringValue HKLM, sKeyPath, "ProductNumber", arrGeneral(1)
    WriteLog"SerialLine is " & arrGeneral(2)
    oReg.SetStringValue HKLM, sKeyPath, "ProductLine",  arrGeneral(2)
    WriteLog"SerialDescription is " & arrGeneral(3)
    oReg.SetStringValue HKLM, sKeyPath, "ProductDescription",  arrGeneral(3)
    WriteLog"WarrantyCheckDate is " & CStr(CDate(arrGeneral(4)))
    oReg.SetStringValue HKLM, sKeyPath, "WarrantyCheckDate",  CStr(CDate(arrGeneral(4)))
    WriteLog"WarrantyType is " & arrContracts(0)
    oReg.SetStringValue HKLM, sKeyPath, "WarrantyType", arrContracts(0)
    WriteLog arrContracts(1)
    WriteLog"HardwareWarrantyStartDate is " & CStr(CDate(arrContracts(1)))
    oReg.SetStringValue HKLM, sKeyPath, "HardwareWarrantyStartDate", CStr(CDate(arrContracts(1)))
    WriteLog"HardwareWarrantyEndDate is " & CStr(CDate(arrContracts(2)))
    oReg.SetStringValue HKLM, sKeyPath, "HardwareWarrantyEndDate", CStr(CDate(arrContracts(2)))
    
EndFunction

Function getStr(startpos, endpos, data)
    Dim tmp
    'Get the substring
    tmp = Mid(data, startpos, endpos - startpos)
    ' Remove end of line
    tmp = Replace(Replace(Replace(tmp, VbCrLf, ""), vbCr, ""), vbLf, "")
    getStr = tmp
EndFunction

Function processTables(table, ttype)
    
    ' Remove HTML Tags and replace with "|"
    Set re = NewRegExp
    re.Pattern = "<[^>]+>"
    re.IgnoreCase = True
    re.Global = True
    table = re.Replace(table, "|")
    
    table = Replace(table, "&nbsp;", "")
    table = Replace(table, ":", "")
    table = Replace(table, "  ", "")
    
    ' Remove excess |
    re.Pattern = "[|]+"
    table = re.Replace(table, "|")
    
    ' Clean up a bit more
    re.Pattern = "\|\s+\|"
    table = re.Replace(table, "|")
    
    ' Remove | from start and end of string
    re.Pattern = "^\||\|$"
    table = re.Replace(table, "")
    
    arrTable = Split(table, "|")
    arrTmp = ""
    
    If ttype = 1Then' General Info Table
        i = 1
        ForEach cellin arrTable
            SelectCaseLCase(Trim(cell))
                Case"serial number"
                    sSerialNumber = arrTable(i)
                Case"product number"
                    sProductNumber = arrTable(i)
                Case"product line"
                    sProductLine = arrTable(i)
                Case"product description"
                    sProductDescription = arrTable(i)
                Case"date of warranty check"
                    sCheckDate = arrTable(i)
            EndSelect
            i = i + 1
        Next
        arrTmp = sSerialNumber & "|" & sProductNumber & "|" & sProductLine & "|" & sProductDescription & "|" & sCheckDate
    ElseIf ttype = 2Then' Contract Info
        i = 0
        ForEach cellin arrTable
            cell = Replace(cell,"                                   ","")
            SelectCaseLCase(Trim(cell))
                Case"warranty type"
                    sWarrantyType = arrTable(i+8)
                Case"wty hp hw maintenance onsite support"
                    sHWStartDate = arrTable(i+1)
                    sHWEndDate = arrTable(i+2)
                    sHWStatus = arrTable(i+3)
                Case"wty hp hw maintenance offsite support"
                    sHWStartDate = arrTable(i+1)
                    sHWEndDate = arrTable(i+2)
                    sHWStatus = arrTable(i+3)
                Case"wty hp support for initial setup"
                    sISStartDate = arrTable(i+1)
                    sISEndDate = arrTable(i+2)
                    sISStatus = arrTable(i+3)
            EndSelect
            i = i + 1
        Next
        arrTmp = sWarrantyType & "|" & sHWStartDate & "|" & sHWEndDate & "|" & sHWStatus & "|" & sISStartDate & "|" & sISEndDate & "|" & sISStatus
    EndIf
    ' Remove | from start and end of string
    re.Pattern = "^\||\|$"
    arrTmp = re.Replace(arrTmp, "")
    'wscript.echo arrTmp
    arrResult = Split(arrTmp, "|")
    
    Set re = Nothing
    
    processTables = arrResult
EndFunction

Function WriteLog (sText)
    If EnableLoggingThen
        oLogfile.WriteLineNow() & "     " & sText
    EndIf
EndFunction

The script logs its results to C:\Windows\Temp\WarrantyInfo.log.

And the information is stored in the registry.

In order to get this information into the SCCM database, we have to modify the Configuration.mof found in C:\Program Files(x86)\Microsoft Configuration Manager\inboxes\clifiles.src\hinv.  (The path may be different depending on where SCCM is installed on the site server.)  Open Configuration.mof, scroll to the bottom and add (making sure to change the references to CompanyName to whatever value you used in the vbscript above):
//=====================================================================
// Warranty Information
//=====================================================================
[DYNPROPS]
class HP_WarrantyInfo
{
 [key] string        Keyname="";
       string        HardwareWarrantyEndDate;
       string        HardwareWarrantyStartDate;
       string        ProductDescription;
       string        ProductLine;
       string        ProductNumber;
       string        SerialNumber;
       string        WarrantyCheckDate;
       string        WarrantyType;
};
[DYNPROPS]
instance of HP_WarrantyInfo
{
     KeyName="WarrantyInformation";
     [PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\CompanyName\\WarrantyInformation|HardwareWarrantyEndDate"), Dynamic, Provider("RegPropProv")] HardwareWarrantyEndDate;
     [PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\CompanyName\\WarrantyInformation|HardwareWarrantyStartDate"), Dynamic, Provider("RegPropProv")] HardwareWarrantyStartDate;
     [PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\CompanyName\\WarrantyInformation|ProductDescription"), Dynamic, Provider("RegPropProv")] ProductDescription;
     [PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\CompanyName\\WarrantyInformation|ProductLine"), Dynamic, Provider("RegPropProv")] ProductLine;
     [PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\CompanyName\\WarrantyInformation|ProductNumber"), Dynamic, Provider("RegPropProv")] ProductNumber;
     [PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\CompanyName\\WarrantyInformation|SerialNumber"), Dynamic, Provider("RegPropProv")] SerialNumber;
     [PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\CompanyName\\WarrantyInformation|WarrantyCheckDate"), Dynamic, Provider("RegPropProv")] WarrantyCheckDate;
     [PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\CompanyName\\WarrantyInformation|WarrantyType"), Dynamic, Provider("RegPropProv")] WarrantyType;
};
Now SCCM will pick up our Warranty information from the registry and add it to the database.  Now we need to get the script to run on the HP systems in the environment.  Create a package and program for the vbscript above and advertise it to a collection.  In order to populte the collection, we have several methods.  We could use standard query rules to get all systems where the manufacturer is HP, but I decided to use DCM instead.
We need a collection of all of our HP systems, so create a collection called HP Systems with a membership rule of:
select
 SMS_R_SYSTEM.ResourceID,
 SMS_R_SYSTEM.ResourceType,
 SMS_R_SYSTEM.Name,
 SMS_R_SYSTEM.SMSUniqueIdentifier,
 SMS_R_SYSTEM.ResourceDomainORWorkgroup,
 SMS_R_SYSTEM.Client
from SMS_R_System
inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_System.ResourceId
where SMS_G_System_COMPUTER_SYSTEM.Manufacturer in ("Hewlett-Packard","HP","HPQOEM")
In the SCCM Console, go to Desired Configuration Management > Configuration Items  and create a new General Configuration Item named Warranty Information and click Next.

Click Next on Objects.
On Settings, select New | Registry

Since the whole purpose of this exercise is to gather warrany information, we are going to look for the HardwareWarrantyEndDate registry key created by our vbscript.  Seth the display name to HardwareWarrantyEndDate, Hive to HKEY_LOCAL_MACHINE, Key to SOFTWARE\CompanyName\WarrantyInformation (again change CompanyName to the value used in the script) and Value name to HardwareWarrantyEndDate.  Click OK to close the New Registry Setting Properties window.

Click Next through the remaining screens in the wizard to complete the creating of the configuration Item.
Now that we have a configuration item to determine if the registry key exists, we need to create a baseline.  Go to Desired Configuration Management > Configuration Baseline and create a new baseline called 'Warranty Information Baseline' and click Next.

Click 'applications and general' and select the Warranty Information configuration item.

Click Next through the remaining screens in the wizard to complete the creating of the configuration baseline.
Right-click the configuration baseline and select 'Assign to a Collection'.
Verify that the Warranty Information Baseline has been added and click Next.
Click Browse and select the HP Systems collection created earlier.
Determine how often you want this baseline to be evaluated, set the schedule and click Next.  The default value of every 7 days should be fine.
Click Next through the remaining screens in the wizard to complete the assignment of the configuration baseline.
Now that we have a baseline and it is assigned, we will begin getting compliance data back.  We can use this compliance data to create a collection of systems that do not have warranty information stored in the registry.
Right -click the 'Warranty Information Baseline' and select Create New Collection > Non-Compliant Systems and select the defaults through the wizard.
You can now use this collection to advertise the Warranty Information script.  Systems that are non-compliant will run the script to populate the registry with the warranty information, therefore becoming compliant and being removed from the collection.
Once the information is in the registry and a hardware inventory cycle is run, you can see the inventory information in Resource Explorer.

Ref : http://adminnexus.blogspot.in/2012/09/including-hp-warranty-information-in.html

1 comment: