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
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!
[…] shot at this I spent some time searching for a better solution in the community. I found this post Get Lenovo Warranty Information with PowerShell by Nickolaj Andersen over at SCConfigMgr, but this solution was also parsing through the web page […]
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
}
Thanks for sharing with us!
Regards,
Nickolaj
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?
Cool! Thanks for sharing 🙂
Regards,
Nickolaj
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
}
Change “services” in the URL to “CSP”
Nikolaj, can the script find out the serialnumber of the computer is it running from?
Also can the information be written to registry so SCCM can pick it up for inventory and report like this: ?
https://sccmguru.wordpress.com/2014/04/24/hp-and-lenovo-warranty-information-in-configuration-manager-2012-r2/
Is there any new links avalible?
Hi John,
I figured this would happen when I wrote the script. Unfortunately I’ve not had any time to check if there’s any new webservice or links to parse through. Perhaps someone else have found any useful material?
Regards,
Nickolaj
They got it working here. I’ve tried it and got the script to work by changing forms[4] to forms[0].
https://social.technet.microsoft.com/Forums/windowsserver/en-US/76d24b85-7ce3-497c-973e-beece6c68ed3/get-lenovo-warranty-info-automatically?forum=winserverpowershell
This lookup website no longer works.
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
I’m seeing 500 errors when querying this service. Just unlucky?
I haven’t go through creating a script, but perhaps you can use their bulk lookup tool at https://csp.lenovo.com/ibapp/il/WarrantyLookupBatch.jsp
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,
I’ve updated the code in the post, could you give it a try again please?
Regards,
Nickolaj
Works great! Thanks for creating this!
Thanks for validating that it works 🙂
Regards,
Nickolaj
This is great and exactly what I was looking for. Small issue for the values that I entered, it is pulling the start date instead of the expiration date.
Example:
Model: 70A0
SN: MJ008E6L
https://services.lenovo.com/ibapp/il/WarrantyStatus.jsp?type=70A0&serial=MJ008E6L
The script displays the 2014-01-18 start date instead of the 2017-01-17 expiration date.
Hi Chris,
Thanks for testing it out! I’ll look into making some adjustments and get back to you 🙂
Regards,
Nickolaj