'################################################################################
'# 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
'################################################