MSEndpointMgr

Get Lenovo Warranty Information with PowerShell

As many of you have probably already seen, some time ago I released the Dell Warranty Status Tool 2.0 as a console extension for ConfigMgr 2012. I’ve received tweets and comments from the community asking for the same kind of console extension for Lenovo and HP. Unfortunately Lenovo doesn’t provide a web service like Dell does (at least to my knowledge), so I’ve been struggling with what approach to use that will be the most stable one. I’ve come up with a basic script that can parse through the web page of Lenovo’s warranty information for a particular system, but I’d like to reach out to the community for a helping hand as I’m not sure if this is the best solution available. Enough talking, here’s the script:

Script

<#
.SYNOPSIS
    Get warranty information for a Lenovo system
.DESCRIPTION
    This script will parse through the warranty information webpage for a particular Lenovo system. Required information is the model and serialnumber of the system.
.PARAMETER Model
    Specify the model information
.PARAMETER SerialNumber
    Specify the SerialNumber
.PARAMETER ShowProgress
    Show a progressbar displaying the current operation
.EXAMPLE
    .\Get-LenovoWarrantyInformation.ps1 -Model "XXXXXXXXXX" -SerialNumber "XXXXXXXX" -ShowProgress
    Get warranty information for a Lenovo system with Model 'XXXXXXXXXX' and SerialNumber 'XXXXXXXX' and show the progress:
.NOTES
    Script name: Get-LenovoWarrantyInformation.ps1
    Author:      Nickolaj Andersen
    Contact:     @NickolajA
    DateCreated: 2015-03-21
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param(
    

[parameter(Mandatory=$true, HelpMessage=”Specify the model information”)]

[ValidateNotNullOrEmpty()] [string]$Model,

[parameter(Mandatory=$true, HelpMessage=”Specify the SerialNumber”)]

[ValidateNotNullOrEmpty()] [string]$SerialNumber,

[parameter(Mandatory=$false, HelpMessage=”Show a progressbar displaying the current operation”)]

[switch]$ShowProgress ) Begin { # Not used } Process { if ($PSBoundParameters[“ShowProgress”]) { $ProgressCount = 0 } $URL = “https://services.lenovo.com/ibapp/il/WarrantyStatus.jsp?type=$($Model)&serial=$($SerialNumber)” $WebRequestResult = Invoke-WebRequest -Uri $URL $TDTagNames = $WebRequestResult.ParsedHtml.getElementsByTagName(“TD”) $TDTagNamesCount = ($TDTagNames | Measure-Object).Count $YearList = New-Object -TypeName System.Collections.ArrayList foreach ($TDTagName in $TDTagNames) { if ($PSBoundParameters) { $ProgressCount++ Write-Progress -Activity “Parsing HTML document” -Id 1 -Status “Processing TD tag $($ProgressCount) / $($TDTagNamesCount)” -PercentComplete (($ProgressCount / $TDTagNamesCount) * 100) } if (($TDTagName.innerHTML -match “\d{4}-\d{2}-\d{2}”) -and ($TDTagName.width -eq 120)) { $ExpirationDate = $TDTagName.innerHTML $YearList.Add($ExpirationDate) | Out-Null } if ($Location -eq $null) { if (($TDTagName.innerHTML -notmatch “<“) -and ($TDTagName.cellIndex -eq 4) -and ($TDTagName.width -eq 140) -and ($TDTagName.innerHTML -notmatch “\d”)) { $Location = $TDTagName.innerHTML } } if (($TDTagName.innerHTML -match “(This).*”) -and ($TDTagName.uniqueNumber -eq 5)) { $Description = $TDTagName.innerHTML } } Write-Progress -Activity “Parsing HTML document” -Id 1 -Completed $PSObject = [PSCustomObject]@{ Model = $Model SerialNumber = $SerialNumber ExpirationDate = $YearList[0] Location = $Location Description = $Description } Write-Output $PSObject }

Using the script

As of right now, the script is basically just for running in a PowerShell console where you manually enter the Model and SerialNumber information of a Lenovo system. My intention is of course to extend this as a console extension for ConfigMgr later.
1. Save the script above as Get-LenovoWarrantyInformation.ps1 to e.g. C:\Scripts.
2. Open a PowerShell console and browse to C:\Scripts.
3. Run the following command:

.\Get-LenovoWarrantyInformation.ps1 -Model 20AR003SMN -SerialNumber PF01GACH -ShowProgress

133_1
That’s the output of the script as of right now, what do you guys think? Could you give it a try and let me know in the comments? I’m very much interested if any of you have made similar scripts but used another method. I’m not very pleased regarding the parsing of the HTML, but hey, you learn as you go.
Thank in advance!

Nickolaj Andersen

Chief Technical Architect and Enterprise Mobility MVP since 2016. Nickolaj has been in the IT industry for the past 10 years specializing in Enterprise Mobility and Security, Windows devices and deployments including automation. Awarded as PowerShell Hero in 2015 by the community for his script and tools contributions. Creator of ConfigMgr Prerequisites Tool, ConfigMgr OSD FrontEnd, ConfigMgr WebService to name a few. Frequent speaker at conferences such as Microsoft Ignite, NIC Conference and IT/Dev Connections including nordic user groups.

25 comments

  • It’s been a while, and combing through this, I’ve updated the Powershell example to return status and fix the description / expiration date issue:
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
    [parameter(Mandatory=$true, HelpMessage=”Specify the model information”)]
    [ValidateNotNullOrEmpty()]
    [string]$Model,
    [parameter(Mandatory=$true, HelpMessage=”Specify the SerialNumber”)]
    [ValidateNotNullOrEmpty()]
    [string]$SerialNumber
    )
    Begin {
    # Not used
    }
    Process {
    $URL = “https://csp.lenovo.com/ibapp/il/WarrantyStatus.jsp?type=$($Model)&serial=$($SerialNumber)”
    $WebRequestResult = Invoke-WebRequest -Uri $URL
    $TDTagNames = $WebRequestResult.ParsedHtml.getElementsByTagName(“Body”)
    foreach ($TDTagName in $TDTagNames)
    {
    $ModelStart = $TDTagName.innerText.indexOf(“Type-Model:”) + “Type-Model:”.Length
    $ModelEnd = $TDTagName.innerText.indexOf(“Serial number:”)
    $Model = $TDTagName.innerText.substring($ModelStart,$ModelEnd – $ModelStart).trim()
    $SerialNumberStart = $TDTagName.innerText.indexOf(“Serial number:”) + “Serial number:”.Length
    $SerialNumberEnd = $TDTagName.innerText.indexOf(“Location:”)
    $SerialNumber = $TDTagName.innerText.substring($SerialNumberStart,$SerialNumberEnd – $SerialNumberStart).trim()
    $Year = $TDTagName.innerText.substring($TDTagName.innerText.indexOf(“End Date: “) + “End Date: “.Length, 10).trim()
    $LocationStart = $TDTagName.innerText.indexOf(“Location:”) + “Location:”.Length
    $LocationEnd = $TDTagName.innerText.indexOf(“Warranty Information”)
    $Location = $TDTagName.innerText.substring($LocationStart,$LocationEnd – $LocationStart).trim()
    $StatusStart = $TDTagName.innerText.indexOf(“Status: “) + “Status: “.Length
    $StatusEnd = $TDTagName.innerText.indexOf(“End Date:“)
    $Status = $TDTagName.innerText.substring($StatusStart,$StatusEnd – $StatusStart).trim()
    $DescriptionSnippet = $TDTagName.innerText.substring($TDTagName.innerText.indexOf(“Description:”) + “Description:”.Length).trim()
    $DescriptionStart = $DescriptionSnippet.indexOf(“Description:”) + “Description:”.Length
    $DescriptionEnd = $DescriptionSnippet.indexOf(“Upgrade Warranty Information“)
    $Description = $DescriptionSnippet.substring($DescriptionStart,$DescriptionEnd-$DescriptionStart).trim()
    }
    $PSObject = [PSCustomObject]@{
    Model = $Model
    SerialNumber = $SerialNumber
    Status = $Status
    ExpirationDate = $Year
    Location = $Location
    Description = $Description
    }
    Write-Output $PSObject
    }

  • Hi Everyone!
    Thank you for this!
    And Sam, thank you for the updated version.
    I made a minor modification, so it automatically pulls the model and serial from the machine its running on. Might not be pretty but Im a total powershell noob 🙂
    Let me know what you think.
    Process {
    $model = Get-WmiObject -Class win32_computersystem | Select-Object -expand model
    $model = $model.Insert(4,’-‘)
    $serialnumber = Get-WmiObject -Class win32_bios | Select-Object -expand serialnumber
    $URL = “https://csp.lenovo.com/ibapp/il/WarrantyStatus.jsp?type=$($Model)&serial=$($SerialNumber)”
    $WebRequestResult = Invoke-WebRequest -Uri $URL
    $TDTagNames = $WebRequestResult.ParsedHtml.getElementsByTagName(“Body”)
    foreach ($TDTagName in $TDTagNames)
    {
    $ModelStart = $TDTagName.innerText.IndexOf(“Type-Model:”) + “Type-Model:”.Length
    $ModelEnd = $TDTagName.innerText.IndexOf(“Serial number:”)
    $Model = $TDTagName.innerText.substring($ModelStart,$ModelEnd – $ModelStart).trim()
    $SerialNumberStart = $TDTagName.innerText.IndexOf(“Serial number:”) + “Serial number:”.Length
    $SerialNumberEnd = $TDTagName.innerText.IndexOf(“Location:”)
    $SerialNumber = $TDTagName.innerText.substring($SerialNumberStart,$SerialNumberEnd – $SerialNumberStart).trim()
    $Year = $TDTagName.innerText.substring($TDTagName.innerText.IndexOf(“ActiveEnd Date: “) + “ActiveEnd Date: “.Length,10)
    $LocationStart = $TDTagName.innerText.IndexOf(“Location:”) + “Location:”.Length
    $LocationEnd = $TDTagName.innerText.IndexOf(“Warranty Information”)
    $Location =$TDTagName.innerText.substring($LocationStart,$LocationEnd – $LocationStart).trim()
    }
    $PSObject = [PSCustomObject]@{
    Model = $Model
    SerialNumber = $SerialNumber
    ExpirationDate = $Year
    Location = $Location
    }
    Write-Output $PSObject
    }

    • I am tweaking this to our needs… Anyway to get Warranty Start Date? I don’t see it on the provided URL, but if you go to warranty status (Different Link) it shows start date also… Thoughts?

  • Quick and dirty, but script now works again 🙂
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
    [parameter(Mandatory=$true, HelpMessage=”Specify the model information”)]
    [ValidateNotNullOrEmpty()]
    [string]$Model,
    [parameter(Mandatory=$true, HelpMessage=”Specify the SerialNumber”)]
    [ValidateNotNullOrEmpty()]
    [string]$SerialNumber
    )
    Begin {
    # Not used
    }
    Process {
    $URL = “https://csp.lenovo.com/ibapp/il/WarrantyStatus.jsp?type=$($Model)&serial=$($SerialNumber)”
    $WebRequestResult = Invoke-WebRequest -Uri $URL
    $TDTagNames = $WebRequestResult.ParsedHtml.getElementsByTagName(“Body”)
    foreach ($TDTagName in $TDTagNames)
    {
    $ModelStart = $TDTagName.innerText.IndexOf(“Type-Model:”) + “Type-Model:”.Length
    $ModelEnd = $TDTagName.innerText.IndexOf(“Serial number:”)
    $Model = $TDTagName.innerText.substring($ModelStart,$ModelEnd – $ModelStart).trim()
    $SerialNumberStart = $TDTagName.innerText.IndexOf(“Serial number:”) + “Serial number:”.Length
    $SerialNumberEnd = $TDTagName.innerText.IndexOf(“Location:”)
    $SerialNumber = $TDTagName.innerText.substring($SerialNumberStart,$SerialNumberEnd – $SerialNumberStart).trim()
    $Year = $TDTagName.innerText.substring($TDTagName.innerText.IndexOf(“ActiveEnd Date: “) + “ActiveEnd Date: “.Length,10)
    $LocationStart = $TDTagName.innerText.IndexOf(“Location:”) + “Location:”.Length
    $LocationEnd = $TDTagName.innerText.IndexOf(“Warranty Information”)
    $Location =$TDTagName.innerText.substring($LocationStart,$LocationEnd – $LocationStart).trim()
    $DescriptionStart = $TDTagName.innerText.IndexOf(“Description:”) + “Description:”.Length
    $DescriptionEnd = $TDTagName.innerText.IndexOf(“Status: ExpiredEnd Date: “)
    $Description = $TDTagName.innerText.substring($DescriptionStart,$DescriptionEnd – $DescriptionStart).trim()
    }
    $PSObject = [PSCustomObject]@{
    Model = $Model
    SerialNumber = $SerialNumber
    ExpirationDate = $Year
    Location = $Location
    Description = $Description
    }
    Write-Output $PSObject
    }

  • Hi
    This is great and exactly what I was looking for but..
    I get this Error, 🙁
    Invoke-WebRequest : Fjärrservern returnerade ett fel: (500) Internt serverfel.
    At C:\Temp\Get-LenovoWarrantyInformation.ps1:40 char:25
    + $WebRequestResult = Invoke-WebRequest -Uri $URL
    Regards
    Avi

  • Hi Nickolaj,
    I have a problem, and your script seems to solve my problem in a kinda way, so I’ll ask you for help!
    Could you make a script where you can upload a file with 8000 computer model/serial numbers from the network adress into lenovo https://csp.lenovo.com/ibapp/il/WarrantyLookupBatch.jsp !
    I need this process to be automated and dowloaded in a repeated time of four months.
    Regards,
    Mo

  • Hi Nickolaj
    We tweeted on Saturday.
    I took a look at your script. I tested it an it works fine. Nice work!
    Regarding differences with ours:
    – We use the Norwegian URL
    – We take only ‘serialnumber’ as parameter
    – Your script displays the description Field (+1)
    – Yours display a progessbar (+1)
    So, as far as I can see, nothing to improve in your script 🙂
    Regards

    • Hi Ernesto,
      Cool! Thank you for your input, it’s indeed very valuable. I still think I need to come up with a better way, since this is dependent on the layout of the HTML to be consistent.
      Regards,
      Nickolaj

  • Correction: Should be 2017-03-03.
    It seems to be because this product has the “service offerings” that also matches the 120 width in the HTML.

    • Hi Chris,
      Thanks for testing it out! I’ll look into making some adjustments and get back to you 🙂
      Regards,
      Nickolaj

Sponsors