retrieving dell warranty data via powershell

first of all, i have to give mad props to mow. he’s crazy good with powershell and deserves massive amounts of respect for his knowledge. i managed to piece together this script from his script on gathering statistical data from the social security website. it was a lot like having 10 of the same pair of everything in different colors and getting dressed in the dark. (no slight to the way you dress, scott. :o)

the concept is pretty straight-forward. dell actually (believe it or not) has a URL that you can append a serial to and retrieve warranty data! through the use of such a novel, sophisticated system, we can employ the html scraping method in powershell to retrieve some data.

for my own edification, we will walk through the script. i’m well aware you know all this.

to begin with, we retrieve the serial # from the command prompt. if it doesn’t exist, we’ll simply quit.

$sSerial = ""

if ($Args[0] -eq $Null) {
  Write-Warning "Please provide a serial number."
  exit
} else {
  $sSerial = $Args[0]
}

moving on, we connect to the dell site and scrape the html source into a variable.

$oWeb = New-Object System.Net.WebClient
$sUrl = "http://support.dell.com/support/topics/global.aspx/support/my_systems_info/details?c=us&l=en&s=gen&~ck=anavml&servicetag=$($sSerial)"
$sData = $oWeb.DownloadString($sUrl)
next, we use a variety of methods to split apart, break up, and seek out the information that we want (since i simply suck at doing good pattern matching, regular expressions, or any other fanciful methods for chunking the data into appropriate bite-size morsels).  NOTE: updated to work with warranty information that’s returned with italics.  i’m certain this fix won’t last long.
$sData = $sData | ForEach-Object { $_ -replace "<i>", "" }
$sData = $sData | ForEach-Object { $_.Split("<") }
$sData = $sData | Select-String "contract"
$sData = $sData | ForEach-Object { $_ -replace $_,"$_`n" }

that last line was because powershell displays things differently than it holds them, it seems. i had to force line breaks in so that my regex statements would match line by line. that’s exactly what we do below. afterwards, we push it back into the variable with just the required values.
$oRegEx = [regex]'"contract_.*row">(.*)'
$cMatches = $oRegEx.Matches($sData)
$cMatches = $cMatches | ForEach-Object { $_.Groups[1].value }
the for loop below uses a method that i found on mow’s site. i have no idea about $foreach.current and $foreach.movenext(). awesome stuff. because of formatting restrictions (should be interpreted as my lack of skill) i’m skipping the first value which is always blank. for the last value, if it’s blank, we’ll insert 0 for the number of days left. otherwise, we insert the value.
$cMyData = @()
foreach ($i in 0..($cMatches.count -1)) {
  $cRecord = New-Object -TypeName system.Object
  [void] $foreach.MoveNext()
  $cRecord | Add-Member -MemberType noteProperty -Name 'Provider' $cMatches[$foreach.current]
  [void] $foreach.MoveNext()
  $cRecord | Add-Member -MemberType noteProperty -Name 'Start Date' $cMatches[$foreach.current]
  [void] $foreach.MoveNext()
  $cRecord | Add-Member -MemberType noteProperty -Name 'End Date' $cMatches[$foreach.current]
  [void] $foreach.MoveNext()
  if ($cMatches[$foreach.current] -ne "") {
      $cRecord | Add-Member -MemberType noteProperty -Name 'Days Left' $cMatches[$foreach.current]
  } else {
      $cRecord | Add-Member -MemberType noteProperty -Name 'Days Left' "0"
  }  
  $cMyData += $cRecord
}

here’s how it looks when you execute it.

.\get-dellwarranty.ps1 ABC123D | ft –AutoSize

Provider Start Date End Date Days Left -------- ---------- -------- --------- QLX 4/24/2008 4/24/2010 316 DELL 4/25/2007 4/24/2010 316

and finally, here’s the completed script.

$sSerial = ""

if ($Args[0] -eq $Null) {
Write-Warning "Please provide a serial number."
exit
} else {
$sSerial = $Args[0]
}

$oWeb = New-Object System.Net.WebClient
$sUrl = "http://support.dell.com/support/topics/global.aspx/support/my_systems_info/details?c=us&l=en&s=gen&~ck=anavml&servicetag=$($sSerial)"
$sData = $oWeb.DownloadString($sUrl)

$sData = $sData | ForEach-Object { $_ -replace "<i>", "" }
$sData = $sData | ForEach-Object { $_.Split("<") }
$sData = $sData | Select-String "contract"
$sData = $sData | ForEach-Object { $_ -replace $_,"$_`n" }

$oRegEx = [regex]'"contract_.*row">(.*)'
$cMatches = $oRegEx.Matches($sData)
$cMatches = $cMatches | ForEach-Object { $_.Groups[1].value }

$cMyData = @()
foreach ($i in 0..($cMatches.count -1)) {
$cRecord = New-Object -TypeName system.Object
[void] $foreach.MoveNext()
$cRecord | Add-Member -MemberType noteProperty -Name 'Provider' $cMatches[$foreach.current]
[void] $foreach.MoveNext()
$cRecord | Add-Member -MemberType noteProperty -Name 'Start Date' $cMatches[$foreach.current]
[void] $foreach.MoveNext()
$cRecord | Add-Member -MemberType noteProperty -Name 'End Date' $cMatches[$foreach.current]
[void] $foreach.MoveNext()
if ($cMatches[$foreach.current] -ne "") {
$cRecord | Add-Member -MemberType noteProperty -Name 'Days Left' $cMatches[$foreach.current]
} else {
$cRecord |
Add-Member -MemberType noteProperty -Name 'Days Left' "0"
}
$cMyData += $cRecord
}

$cMyData

Comments

  1. Seems to be a bug somewhere.. look at 431P5J1. It reports 0 for warranty, but the website says otherwise.

    ReplyDelete
  2. hey anonymous -

    i updated the script. works now!

    ReplyDelete
  3. If you add just two more lines, you can get the description of the warranty as well:

    ------------------------------------

    # First Edit: This just strips out the style tag before the description data that we didn't want

    $sData = $oWeb.DownloadString($sUrl)
    $sData = $sData -creplace '!a style.*?!', ''

    # (Replace the !'s with greater than / less than signs. The comment box wouldn't allow them.)
    ------------------------------------

    # Second Edit: This adds the Description property to our results

    $cRecord = New-Object -TypeName system.Object
    $cRecord | Add-Member -MemberType noteProperty -Name 'Description' $cMatches[$foreach.current]
    [void] $foreach.MoveNext()
    $cRecord | Add-Member -MemberType noteProperty -Name 'Provider' $cMatches[$foreach.current]

    ReplyDelete
  4. thanks for that, jerris. that rocks!

    ReplyDelete
  5. This is great stuff, but I had to play with the URL's depending on the system.

    $oWeb = New-Object System.Net.WebClient
    $sUrl = "http://support.dell.com/support/topics/global.aspx/support/my_systems_info/details?c=us&l=en&s=biz&&servicetag=$($sn.serialnumber)"
    $sData = $oWeb.DownloadString($sUrl)

    if ($sData.Contains("Server Processing Error")){
    $sUrl = "http://support.dell.com/support/topics/global.aspx/support/my_systems_info/details?c=us&cs=555&l=en&s=bsdr&servicetag=$($sn.serialnumber)"
    $sData = $oWeb.DownloadString($sUrl)
    }

    ReplyDelete
  6. david -- don't get me started. it seems like someone changes the format near weekly and starts another tailspin. every time i run it, it's a crap shoot whether or not i'm actually going to get good, usable data.

    i ran into some dell folks at mms. they swear they're looking in the webservice idea. 2010. really?

    ReplyDelete
  7. This seems to work if you are only interested in the start and end dates...

    $oWeb = New-Object System.Net.WebClient
    $sUrl = "http://support.dell.com/support/topics/global.aspx/support/my_systems_info/details?c=us&l=en&s=gen&~ck=anavml&servicetag=$($sSerial)"
    $sData = $oWeb.DownloadString($sUrl)
    #get just the dates from the dell site.
    $oRegEx = [regex]'\d{1,2}/\d{1,2}/\d{4}'
    $cMatches = $oRegEx.Matches($sData)

    $test = @()
    foreach ($a in $cMatches){$Test += ([datetime]$a.Value)}
    $datedata = $test | Sort-Object year

    $ShipDate = ($Datedata[0]).toshortdatestring()
    #Find the last object in the array
    $cDates = ($Datedata.count) - 1
    #Grab the latest date from the array for the warranty end date
    $EndDate = ($Datedata[$cDates]).toshortdatestring()
    #Output to console...
    Write-Host Serial Number: $sSerial ShipDate: $ShipDate EndDate: $EndDate

    ReplyDelete
  8. Looks like Dell changed their site, I don't see where they are passing the service tag to a URL anymore =(

    ReplyDelete
  9. it was horribly inconsistent. try this one instead, which uses an unpublished dell webservice --

    http://marcusoh.blogspot.com/2011/08/sccm-integrating-dell-warranty-data.html

    ReplyDelete

Post a Comment