'################################################################################ '# warrantyInfo.vbs - Version 0.5 # '# Copyright 2010 Ryan McLean (ryan1_00 _A_T_ hotmail _D_O_T_ com) # '# # '# License: GPL v2 or later # '# # '# Thanks to: # '# Sherry Kissinger for posting the original script (I found it on myitforum) # '# Chris Duszenski for the Updated version of the script that this is based on # '# # '# Notes: # '# You MUST update your sms_def.mof file with the code below if you want # '# to use the WMI for capturing. IT IS DIFFERENT from other versions of # '# this script # '# # '# Disclaimer: # '# This script "works for me", it may break your network, it may cause # '# world war 3. If it does, or even if it doesn't work at all, I am not # '# not liable, there is no warranty implied or otherwise. # '# By using the script you agree that anything it does or doesn't do is your # '# own fault and not mine. # '# # '# If in doubt read the code, all improvements, suggestions and fixs welcome # '# # '# # '################################################################################ On Error Resume Next '############# USER CHANGEABLE CONSTANTS ######## ' URL for dell service information Const DELLSUPPORTURL = "http://support.dell.com/support/topics/global.aspx/support/my_systems_info/details?c=us&l=en&s=gen&~tab=1&ServiceTag=" ' Version Number here should match the SMS_DEF.mof file line: ' CUSTOM|Warranty_Info|X.X Const SMSDEFVERSION = "3.0" ' Logging Const LOG = false Const LOGFILE = "C:\Windows\Logs\SCCM-Dell_Warranty_Info.log" ' Write output to file instead of to WMI Const TOFILE = false Const OUTFILE = "C:\warrantyInfo.csv" ' HTML File to use for testing Const USETESTFILE = false Const HTMLFILE = "C:\service.html" '################################################ '############# CALL MAIN ######################## Main() '################################################ '############# CONSTANTS ######################## ' File I/O Const forREADING = 1 Const forWRITING = 2 Const forAPPENDING = 8 ' WMI Const wbemCimtypeSint16 = 2 Const wbemCimtypeSint32 = 3 Const wbemCimtypeReal32 = 4 Const wbemCimtypeReal64 = 5 Const wbemCimtypeString = 8 Const wbemCimtypeBoolean = 11 Const wbemCimtypeObject = 13 Const wbemCimtypeSint8 = 16 Const wbemCimtypeUint8 = 17 Const wbemCimtypeUint16 = 18 Const wbemCimtypeUint32 = 19 Const wbemCimtypeSint64 = 20 Const wbemCimtypeUint64 = 21 Const wbemCimtypeDateTime = 101 Const wbemCimtypeReference = 102 Const wbemCimtypeChar16 = 103 '################################################ '############# MAIN() ########################### Sub Main() 'wscript.echo "Main.." Dim strServicetag, rawHTML strServicetag = "" ScriptRunDate = Now 'wscript.echo ScriptRunDate If LOG = true Then strErr = now & ",Main," & "," & "Script starting" Call writeFile (strErr, true) End If 'wscript.echo "Get Service Tag..." strServicetag = getServiceTag() 'wscript.echo strServicetag 'wscript.echo "Get Dell Support Page..." If USETESTFILE = false Then If LOG = true Then strErr = now & ",Main," & "," & "Getting Dell Page from Web" Call writeFile (strErr, true) End If rawHTML = getDellSupportPage(strServicetag) Else If LOG = true Then strErr = now & ",Main," & "," & "Getting Dell Page from File:" & HTMLFILE Call writeFile (strErr, true) End If rawHTML = readFile(HTMLFILE) End If 'wscript.echo "Process HTML" arrData = processHTML(rawHTML) If TOFILE = false Then If LOG = true Then strErr = now & ",Main," & "," & "Output to WMI" Call writeFile (strErr, true) End If 'wscript.echo "Delete WMI Warranty Info.." call deleteWMIWarrantyInfo() 'wscript.echo "Create WMI Warranty Info Class.." call CreateWMIWarrantyInfoClass() 'wscript.echo "Populate WMI Warranty Info.." call populateWMIWarrantyInfo(arrData,ScriptRunDate) Else If LOG = true Then strErr = now & ",Main," & "," & "Output to File" Call writeFile (strErr, true) End If strData = prepareForFile(arrData,ScriptRunDate) call writeFile(strData, false) End If 'wscript.echo "Done" If LOG = true Then strErr = now & ",Main," & "," & "Script Finished" Call writeFile (strErr, true) End If wscript.quit(0) End Sub '################################################ '############# FUNCTIONS AND SUB ROUTINES ####### Function getServiceTag() 'wscript.echo "Getting Service Tag..." Dim objSWbemServices, colSWbemObjectSet, objSWbemObject, stag Set objSWbemServices = GetObject("winmgmts:\\.\root\cimv2") Set colSWbemObjectSet = objSWbemServices.ExecQuery("SELECT * FROM win32_bios") For Each objSWbemObject In colSWbemObjectSet stag = objSWbemObject.SerialNumber Next If LOG = true Then strErr = now & ",getServiceTag," & "," & "Service Tag: " & stag Call writeFile (strErr, true) End If getServiceTag = stag End Function Function getDellSupportPage(tag) 'wscript.echo "Getting Dell Support Page..." Dim strURL, objHTTP strURL = DELLSUPPORTURL & tag Set objHTTP = CreateObject("Msxml2.XMLHTTP") objHTTP.open "GET", strURL, False objHTTP.send If objHTTP.status = 200 Then getDellSupportPage = objHTTP.responseText else strErr = now & ",getDellSupportPage," & objHTTP.status & "," & "Description: " & objHttp.GetErrorDescription(objHttp.LastError) 'wscript.echo strErr If LOG = true Then Call writeFile (strErr, true) End If wscript.quit(1) End If End Function Function processHTML(html) 'wscript.echo "Processing HTML..." ' Declare Dim intSummaryPos, intSummaryTable1Start, intSummaryTable1End, intSummaryTable2Start Dim intSummaryTable2End Dim table1, table2 'Initialise intSummaryPos = 0 intSummaryTable1Start = 0 intSummaryTable1End = 0 intSummaryTable2Start = 0 intSummaryTable2End = 0 table1 = "" table2 = "" 'Process intSummaryPos = InStr(LCase(html), "service tag:") 'wscript.echo "Summary Start: " & intSummaryPos If intSummaryPos > 0 Then intSummaryTable1Start = InStrRev(LCase(html), "") + 8 intSummaryTable2Start = InStr(intSummaryTable1End, LCase(html), "") 'wscript.echo "T1S: " & intSummaryTable1Start & vbcrlf & "T1E: " & _ ' intSummaryTable1End & vbcrlf & "T2S: " & intSummaryTable2Start & _ ' vbcrlf & "T2E: " & intSummaryTable2End End If table1 = getSStr(intSummaryTable1Start, intSummaryTable1End, html) 'wscript.echo "table1: " & vbcrlf & table1 table2 = getSStr(intSummaryTable2Start, intSummaryTable2End, html) 'wscript.echo "table2: " & vbcrlf & table2 ' "Service Tag, System Type, Ship Date, Dell IBU" arrGeneral = processTables(table1,1) ' "Description, Provider, Start Date, End Date, Days Left" arrContracts = processTables(table2,2) 'Clean up the contracts arrContracts = CleanContracts(arrContracts) ' Make single array strDetails = "" For Each x in arrGeneral strDetails = strDetails & "|" & trim(x) Next For Each x in arrContracts strDetails = strDetails & "|" & trim(x) Next strDetails = Right(strDetails, len(strDetails) - 1) arrDetails = Split(strDetails, "|") If LOG = true Then strErr = now & ",processHTML," & "," & "Details Returned: " & strDetails Call writeFile (strErr, true) End If 'wscript.echo strDetails processHTML = arrDetails End Function Function getSStr(startpos, endpos, data) 'wscript.echo "Getting Sub-String.." Dim tmp 'wscript.echo "Start: " & startpos & vbcrlf & "End: " & endpos & vbcrlf & "Diff: " & endpos - startpos 'Get the substring tmp = Mid(data, startpos, endpos - startpos) ' Remove end of line tmp = Replace(Replace(Replace(tmp, VbCrLf, ""), vbCr, ""), vbLf, "") getSStr = tmp End Function Function processTables(table, ttype) 'wscript.echo "Processing Table..." ' Remove HTML Tags and replace with "|" Set re = New RegExp re.Pattern = "<[^>]+>" re.IgnoreCase = True re.Global = True table = re.Replace(table, "|") table = Replace(table, "Change Service Tag", "") 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, "") 'wscript.echo table arrTable = Split(table, "|") arrTmp = "" If ttype = 1 Then ' General Info Table i = 1 For Each cell in arrTable If i MOD 2 = 0 Then 'wscript.echo cell arrTmp = arrTmp & "|" & cell End If i = i + 1 next ElseIf ttype = 2 Then ' Contract Info i = 0 For Each cell in arrTable If i > 5 Then 'wscript.echo cell arrTmp = arrTmp & "|" & cell End If i = i + 1 next End If ' Remove | from start and end of string re.Pattern = "^\||\|$" arrTmp = re.Replace(arrTmp, "") 'wscript.echo arrTmp arrResult = Split(arrTmp, "|") Set re = Nothing processTables = arrResult End Function Function CleanContracts(array) 'wscript.echo "Cleaning Contracts.." ' If there is a list of contracts like so: ' ' "Description", "Warranty Extension Notice", "Provider", "Ship Date", "Start Date", "Days Left" ' Dell Business Support / ProSupport, "No", DELL, 2/20/2008, 2/20/2012, 712 ' Next Business Day, "No", DELL, 2/20/2008, 2/20/2012, 712 ' Next Business Day, "No", DELL, 2/20/2008, 2/20/2011, 347 ' ' We Don't care about the NBD, 347 Day contract as we have extended ' So we only want to report on the 712 day contract as that is what is ' in effect. ' However as the 347 Day contract is last it will be the last one entered ' and so overwrite the 712 day contract. ' This function compares the contracts and if the Descriptions are the same ' compares the days left and keeps only the longest. intLoopCount = (UBound(array)+1) / 6 shortlist = "" For i = 1 To intLoopCount intMultiplier = 6*(i-1) 'wscript.echo array(0+intMultiplier) ' Description 'wscript.echo array(4+intMultiplier) ' Days Left For x = 1 To intLoopCount multiplier2 = 6*(x-1) 'wscript.echo "1: " & intMultiplier & vbcrlf & "2: " & multiplier2 If intMultiplier <> multiplier2 Then If array(0+intMultiplier) = array(0+multiplier2) Then If array(5+intMultiplier) > array(5+multiplier2) Then shortlist = shortlist & "|" & multiplier2 End If End If End If Next Next arrShortlist = split(shortlist, "|") strNewArr = "" slmatch = false For i = 0 To UBound(array) 'wscript.echo array(i) strNewArr = strNewArr & "|" & array(i) For Each intShortlist in arrShortlist If i = (cint(intShortlist)-1) Then i = i + 5 slmatch = true End If Next Next if slmatch = true then extension = "true" else extension = "false" end if strNewArr = extension & strNewArr 'wscript.echo strNewArr CleanContracts = split(strNewArr, "|") End Function Sub deleteWMIWarrantyInfo() on error resume next 'wscript.echo "Deleting WMI Warranty Info.." Set oLocation = CreateObject("WbemScripting.SWbemLocator") 'Remove classes Set oServices = oLocation.ConnectServer(, "root\cimv2") Set oNewObject = oServices.Get("Warranty_Info") If Err.Number = -2147217406 Then strErr = now & ",deleteWMIWarrantyInfo,,WMI Class 'Warranty_Info' does not exist" If LOG = true Then Call writeFile (strErr, true) End If ElseIF Err.Number <> 0 Then strErr = now & ",deleteWMIWarrantyInfo," & Err.Number & "," & Err.Description If LOG = true Then Call writeFile (strErr, true) End If Else oNewObject.Delete_ If LOG = true Then strErr = now & ",deleteWMIWarrantyInfo," & "," & "Warranty_Info class deleted" Call writeFile (strErr, true) End If End If Set oLocation = Nothing Set oServices = Nothing End Sub Sub CreateWMIWarrantyInfoClass() 'wscript.echo "Creating WMI Warranty Info Class.." Set oLocation = CreateObject("WbemScripting.SWbemLocator") Set oServices = oLocation.ConnectServer(, "root\cimv2") 'Create data class structure Set oDataObject = oServices.Get oDataObject.Path_.Class = "Warranty_Info" oDataObject.Properties_.add "DateScriptRan", wbemCimtypeString oDataObject.Properties_.add "ServiceTag", wbemCimtypeString oDataObject.Properties_.add "SystemType", wbemCimtypeString oDataObject.Properties_.add "ShipDate", wbemCimtypeString oDataObject.Properties_.add "DellIBU", wbemCimtypeString oDataObject.Properties_.add "Description", wbemCimtypeString oDataObject.Properties_.add "Provider", wbemCimtypeString oDataObject.Properties_.add "StartDate", wbemCimtypeString oDataObject.Properties_.add "EndDate", wbemCimtypeString oDataObject.Properties_.add "DaysLeft", wbemCimtypeUint32 oDataObject.Properties_.add "WarrantyExtended", wbemCimtypeString oDataObject.Properties_("Description").Qualifiers_.add "key", True oDataObject.Put_ Set oLocation = Nothing Set oServices = Nothing Set oDataObject = Nothing End Sub Sub populateWMIWarrantyInfo(data, sRunDate) 'wscript.echo "Populating WMI Warranty Info.." Set oLocation = CreateObject("WbemScripting.SWbemLocator") Set oServices = oLocation.ConnectServer(, "root\cimv2") 'Calc contracts intContractCount = UBound(data) - 4 'wscript.echo "Total elements: " & UBound(data) & vbcrlf & _ ' "Contract Elements: " & intContractCount intLoopCount = intContractCount / 6 'wscript.echo "Number of Loops: " & intLoopCount 'Populate For i = 1 To intLoopCount 'wscript.echo "DateScriptRan: " & sRunDate 'wscript.echo "ServiceTag: " & data(0) 'wscript.echo "SystemType: " & data(1) 'wscript.echo "ShipDate: " & data(2) 'wscript.echo "DellIBU: " & data(3) 'wscript.echo "Description: " & data(5+(5*(i-1))) 'wscript.echo "Provider: " & data(7+(5*(i-1))) 'wscript.echo "StartDate: " & data(8+(5*(i-1))) 'wscript.echo "EndDate: " & data(9+(5*(i-1))) 'wscript.echo "DaysLeft: " & data(10+(5*(i-1))) 'wscript.echo "WarrantyExtended: " & data(4) Set oNewObject = oServices.Get("Warranty_Info").SpawnInstance_ oNewObject.DateScriptRan = sRunDate oNewObject.ServiceTag = data(0) oNewObject.SystemType = data(1) oNewObject.ShipDate = data(2) oNewObject.DellIBU = data(3) oNewObject.Description = data(5+(5*(i-1))) oNewObject.Provider = data(7+(5*(i-1))) oNewObject.StartDate = data(8+(5*(i-1))) oNewObject.EndDate = data(9+(5*(i-1))) oNewObject.DaysLeft = data(10+(5*(i-1))) oNewObject.WarrantyExtended = data(4) oNewObject.Put_ Next Set oLocation = Nothing Set oServices = Nothing Set oNewObject = Nothing End Sub Function prepareForFile(data, sRunDate) 'Preparing outstring 'Calc contracts intContractCount = UBound(data) - 5 'wscript.echo "Total elements: " & UBound(data) & vbcrlf & _ ' "Contract Elements: " & intContractCount intLoopCount = intContractCount / 6 'wscript.echo "Number of Loops: " & intLoopCount outString = "'DateScriptRan','ServiceTag','SystemType','ShipDate','DellIBU','WarrantyExtended'," outstring = outString & "'Description','Provider','Warranty Extension Notice','StartDate','EndDate','DaysLeft'" 'Populate 'Create For i = 1 To intLoopCount outString = outString & vbcrlf outString = outString & "'" & sRunDate & "'," outString = outString & "'" & data(0) & "'," outString = outString & "'" & data(1) & "'," outString = outString & "'" & data(2) & "'," outString = outString & "'" & data(3) & "'," outString = outString & "'" & data(4) & "'," outString = outString & "'" & data(5+(5*(i-1))) & "'," outString = outString & "'" & data(6+(5*(i-1))) & "'," outString = outString & "'" & data(7+(5*(i-1))) & "'," outString = outString & "'" & data(8+(5*(i-1))) & "'," outString = outString & "'" & data(9+(5*(i-1))) & "'," outString = outString & "'" & data(10+(5*(i-1))) & "'," Next outString = Left(outString, len(outString)-1) 'wscript.echo outString prepareForFile = outString End Function Sub writeFile(data, islog) 'wscript.echo "Writing file" Set myFSO = CreateObject("Scripting.FileSystemObject") If islog = true Then 'wscript.echo "Writing to: " & LOGFILE Set myfile = myFSO.OpenTextFile(LOGFILE, forAPPENDING, True) Else 'wscript.echo "Writing to: " & OUTFILE Set myfile = myFSO.OpenTextFile(OUTFILE, forWRITING, True) End If myfile.WriteLine(data) myfile.Close Set myfile = Nothing Set myFSO = Nothing End Sub '################################################ '############# TEST FUNCTIONS AND SUB ROUTINES ## Function readFile(infile) ' Used to read in an HTML page that has been ' copied from the vendor site in order to reduce ' the hits on their site while testing 'wscript.echo "Reading file: " & infile Dim objFSO, objFile, objReadFile Dim strContents Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.GetFile(infile) If objFile.Size > 0 Then Set objReadFile = objFSO.OpenTextFile(infile, forREADING) strContents = objReadFile.ReadAll objReadFile.Close Else Wscript.Echo "The file is empty." End If 'wscript.echo strContents readFile = strContents End Function '################################################