Thursday 10 February 2011

Using Opalis to automate the gathering of Dell Warranty information and update Service Manager with it

For ages now there has been various vb scripts around that has allowed the Dell Warranty website to be checked in a scripted fashion by passing a service tag number across in a url and parsing the returned html for the required information.

One really cool usage of this was using ConfigMgr to run the script on PC's and add the information into WMI for inventorying later via mof edits.
Sherry Kissinger has an excellent article here:

While this is great for active clients, once the device is decommissioned or you have problems with the client and remove it from SCCM for one reason or another, your data is gone!  Not so good for long term reporting or asset management.

Since I'm in the process of migrating all of our asset management reporting and information storage into Service Manager 2010, warranty expiration, start date, type etc was one of the main items of information that we needed to store so I started to think how I could automate this as much as possible.

3 Options sprang to mind:
  1. Supply Dell with a list of all our service tags and then CSV import it - allows large bulk updates but takes time if large volumes of updates required again.
  2. Implement the SCCM scripts then create a custom connector to gather the data - overly complex for my liking and duplicates the information storage
  3. Use Opalis to gather the data and update Service Manager - Sounded cool ;)
I went with option 3 mainly because it sounded like a cool idea to play with, but also seemed the most straight forward.

Things to note:
  • This is proof of concept, failure handling etc would need adding for production
  • I've extended the Windows Computer class in advance with a "Warranty Expiration Date" property.  You could in theory extend any class to hold it, Computer (Deployed) might be more fitting but I've got other reasons for choosing the Windows Computer class.

So.... I created a policy that looks something like this:

First step is to get the GUID's of the Windows Computer objects, and then query them for their relationships with Computer (Deployed) objects.
Second Step is to then get the related Computer (Deployed) object which then gives us access to the Serial Number (Dell service tag) via the Opalis Databus and then pass it across to a Powershell Script.

 This is basically where the "magic" happens, the powershell script.
All credit for this goes to Marcus Oh and his blog post here:

I've only tweaked his PS code slightly by adding proxy details so that I could get out of our network, added an underscore ( _ ) to the $sData = $sData | Select-String "contract_" line to stop an error about javascript that was happening and flattened the output by adding $Warranty =$cMyData | foreach {$_.EndDate} to only output the warranty end date.  Same principal could be applied for start date, days left etc or output it all and do the manipulation in Opalis.

$sSerial = "{Serial Number from "Get Object - Computer (Deployed)"}"
$oWeb = New-Object System.Net.WebClient
$proxy = New-Object System.Net.WebProxy("YourProxyServerHere:8080")
$proxy.UseDefaultCredentials = $true
$oWeb.proxy = $proxy
$sUrl = "$($sSerial)"
$sData = $oWeb.DownloadString($sUrl)
$sData = $sData -creplace '<a style.*?>', ''
$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 'StartDate' $cMatches[$foreach.current]
    [void] $foreach.MoveNext()
    $cRecord | Add-Member -MemberType noteProperty -Name 'EndDate' $cMatches[$foreach.current]
    [void] $foreach.MoveNext()
    if ($cMatches[$foreach.current] -ne "") {
        $cRecord | Add-Member -MemberType noteProperty -Name 'DaysLeft' $cMatches[$foreach.current]
    } else {
        $cRecord |
        Add-Member -MemberType noteProperty -Name 'DaysLeft' "0"
    $cMyData += $cRecord
$Warranty = $cMyData | foreach {$_.EndDate}

Final steps, we'll split the incoming data to make it easier to handle, we'll assume for this PoC that the FIRST field returned is the correct warranty expiration date (it seemed to be in all the ones I manually checked).

Then we'll format that returned data into a date format that can be used by Service Manager.

Then finally we'll update the extended property created earlier with the information.

Et Voila!  This could either be setup now to run when objects are updated by using the "Monitor Object" SCSM IP component and scoping it for updated serial number properties, or schedule it to run at scheduled times or even just manually when you desire.

Remember, this is proof of concept, it works in my test lab, but will need developing and testing before you would use it in a production environment.


radtravis said...

Super Cool!

Steve Beaumont said...

Thanks Travis, keep an eye out for the next post, complete end to end provisioning of new systems including AD Account creation, ConfigMgr record pre-staging, Service Manager Asset Creation and then linking it all to the device being replaced and copying all the info across like AD groups, SCCM collections and Service Manager relationship linking.

Pete said...

I have been using pieces of the following code at to retrieve warranty info. It fixes the formatting issues from the posted PS script

Marcus Oh said...

thanks for the credit! did you see that dell has a webservice now? i couldn't rely on that script since data scraping was a full time job for every time they changed their website. :)

unfortunately the last time i checked, the webservice wasn't returning warranty data. :(

Steve Beaumont said...

I saw your post Marcus on using the webservice.

I was trying to find time to change it into an Orchestrator runbook, but if it's not working now, that's blown it :(

Mike said...

Try this: