O R G A N I C / F E R T I L I Z E R: retrieving dell warranty data via powershell

Jun 12, 2009

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