[PowerShell] / Get-HpProductInfo.ps1 Repository:
ViewVC logotype

View of /Get-HpProductInfo.ps1

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (download) (annotate)
Sat Aug 24 23:56:19 2013 UTC (10 years, 7 months ago) by ian
File size: 17444 byte(s)
Get-HpProductInfo.ps1:
replaced some XML collections of data with hash tables and arrays to improve speed and use less code;
partially done modifying code to output an object instead of plain text;
þÿ##################################################

#

#  Written by Ian Cammarata

#  Get-HpProductInfo.ps1 v0.1

#

##################################################

#

#  Usage:

#    Get-HpProductInfo < serial number >

#  Ex:

#    Get-HpProductInfo JPBCD3R1H3

#

##################################################

#

#  Notes:

#    -Will probably only work for products sold in the US unless you change the country

#     codes in $hpWarrantyQueryURL and the $htClient.Headers.set(...Cookie...

#

#  To Do:

#    -Make it a proper PowerShell script (receive piped input, input validation, multiple SNs at once)

#    -Internally place data into an object so it can be exported to an XML cache for

#     faster loading if the same SN is queried again.

#    -Multi-threading the http downloads and multiple retry attemps (partsufer is so unreliable lately)

#    -Option to filter parts output

#

##################################################



Set-StrictMode -Version Latest



$lookupSn = "CND120CJH0"

if ($args) { $lookupSn = $args[0] }



#SNs to test with CND120CJH0, CNU305BP9N, CNFKF52058, JPBCD3R1H3



$partSurferQueryUrl = "http://partsurfer.hp.com/Search.aspx?searchText="

$hpWarrantyQueryUrl = "http://h20000.www2.hp.com/bizsupport/TechSupport/WarrantyResults.jsp?lang=en&cc=us&country=US&find=Display+Warranty+Information+%C2%BB"





### Create WebClient and cookie needed for PartSurfer

$htClient = New-Object System.Net.Webclient

$htClient.Headers.Set([System.Net.HttpRequestHeader]::Cookie, "Country=United%20States")





### Download and clean PartSurfer HTML so it can be parsed into XML

$ErrorActionPreference = "Stop" #Needed so script won't continue if the web server returns an error

$htData = $htClient.DownloadString("$($partSurferQueryUrl)$($lookupSn)")

$htData = -join $htData[$htData.IndexOf("<body")..($htData.LastIndexOf("</body>")+6)]

$htData = $htData -replace '(?sx:<script[\s\S]*?</script[\s\S]*?>)' -replace '(?sx:<noscript[\s\S]*?</noscript[\s\S]*?>)'

$htData = $htData -replace ' & ', " and " -replace "&\w{2,6};"

$partSurferXml = [xml]$htData





### Parse collections of data

$ErrorActionPreference = "SilentlyContinue" #Needed so filtering by ID won't generate an error on nodes with no ID property

#XML Collections

$skuXmlObjects = $partSurferXml.SelectNodes("//span") | # SN, Sku, Description

    ? { $_.id -like "*lbl*" -and $_.id -notlike "*BOM*" -and $_.id -notlike "*text*" }

$partXmlObjects = $partSurferXml.SelectNodes("//span") | # Parts

    ? { $_.id -like "*gridSpareBOM_ctl*" -and $_.'#text' -notlike "*N/A*" } 

$orderCheckboxXmlObjects = $partSurferXml.SelectNodes("//input") |  # Collection of checkboxes indicating part is orderable

    ? { $_.id -like "*chkSpareBOM" }



#Hash or Array Collections (This will be much faster than XML?)

$partsHash = @{}

$partSurferXml.SelectNodes("//span") | ? { $_.id -like "*gridSpareBOM_ctl*" -and $_.'#text' -notlike "*N/A*" } |

    % { $partsHash[$_.id] = $_.'#text' }

    

$orderCheckboxArray = @()

$partSurferXml.SelectNodes("//input") | ? { $_.id -like "*chkSpareBOM" } | % { $orderCheckboxArray += $_.id }



$ErrorActionPreference = "Continue"





### Extract SN, Sku, Description

$serialNumber = ($skuXmlObjects | ?{$_.id -like "*SerialNumber"}).'#text'

$productNumber = ($skuXmlObjects | ?{$_.id -like "*ProductNumber"}).'#text'

$productDescr = ($skuXmlObjects | ?{$_.id -like "*Description"}).'#text'





### Create psObject and start adding to it

$hpProduct = New-Object psObject

<#

$hpProduct | Add-Member NoteProperty SerialNumber ($skuXmlObjects | ?{$_.id -like "*SerialNumber"}).'#text'

$hpProduct | Add-Member NoteProperty ProductNumber ($skuXmlObjects | ?{$_.id -like "*ProductNumber"}).'#text'

$hpProduct | Add-Member NoteProperty Description ($skuXmlObjects | ?{$_.id -like "*Description"}).'#text'

#>

$hpProduct | Add-Member NoteProperty Parts (New-Object psObject) -force





### Extract orderable U.S. parts

<#Using XML takes 6 times as long as new function using hashes

$orderableParts = @()

$partsObjects = @()

foreach ( $part in ( $partXmlObjects | ? { $_.id -like "*lblspart1" } ) ) {

    if ( $part.id -match ".*(_ctl\d{2,3}_).*" ) {

        if ( $orderCheckboxXmlObjects | ? { $_.id -like "*$($matches[1])*" } ) {

            #6.5 seconds

            $newPart = ($partXmlObjects | ? { $_.id -like "*$($matches[1])*" -and $_.id -notlike "*Enhanced" } | % { $_.'#text' }) -join "`t"

            $orderableParts += $newPart

            

            #35 seconds

            $partObject = New-Object psObject

            $partObject | Add-Member NoteProperty PartNumber ($partXmlObjects | ? { $_.id -like "*$($matches[1])*" -and $_.id -like "*spart1" }).'#text'

            $partObject | Add-Member NoteProperty Description ($partXmlObjects | ? { $_.id -like "*$($matches[1])*" -and $_.id -like "*desc1" }).'#text'

            $partObject | Add-Member NoteProperty EnhancedDescription ($partXmlObjects | ? { $_.id -like "*$($matches[1])*" -and $_.id -like "*Enhanced" }).'#text'

            $partObject | Add-Member NoteProperty Category ($partXmlObjects | ? { $_.id -like "*$($matches[1])*" -and $_.id -like "*Category1" }).'#text'

            $partObject | Add-Member NoteProperty CSR ($partXmlObjects | ? { $_.id -like "*$($matches[1])*" -and $_.id -like "*CSR1" }).'#text'

            $partObject | Add-Member NoteProperty ROHS ($partXmlObjects | ? { $_.id -like "*$($matches[1])*" -and $_.id -like "*Rohs1" }).'#text'

            $partObject | Add-Member NoteProperty Tech ($partXmlObjects | ? { $_.id -like "*$($matches[1])*" -and $_.id -like "*tech1" }).'#text'          

            $partsObjects += $partObject

            

        }

    }

}#>

#Using Hash Table

#$partsObjects = @()

foreach ( $cb in $orderCheckboxArray ) {

    $null = $cb -match ".*(_ctl\d{2,3}_).*"

    $curPartData = $partsHash.GetEnumerator() | ? { $_.Name -like "*$($Matches[1])*" }

    $partObject = New-Object psObject

    foreach ( $part in $curPartData.GetEnumerator() ) {

        $propName = "WTF"

        switch -wildcard ($part.Name) {

            "*spart1" { $propName ="PartNumber" }

            "*desc1" { $propName ="Description" }

            "*Enhanced" { $propName ="EnhancedDescription" }

            "*Category1" { $propName ="Category" }

            "*CSR1" { $propName ="CSR" }

            "*Rohs1" { $propName ="ROHS" }

            "*tech1" { $propName ="Tech" }

             default { continue }

        }

        $partObject | Add-Member NoteProperty $propName $part.Value

    }

    #$partsObjects += $partObject

    

}

foreach ( $cb in $orderCheckboxArray ) {

    $null = $cb -match ".*(_ctl\d{2,3}_).*"

    $curPartData = $partsHash.GetEnumerator() | ? { $_.Name -like "*$($Matches[1])*" }

    $partObject = New-Object psObject

    foreach ( $part in $curPartData.GetEnumerator() ) {

        $propName = "WTF"

        switch -wildcard ($part.Name) {

            "*spart1" { $propName ="PartNumber" }

            "*desc1" { $propName ="Description" }

            "*Enhanced" { $propName ="EnhancedDescription" }

            "*Category1" { $propName ="Category" }

            "*CSR1" { $propName ="CSR" }

            "*Rohs1" { $propName ="ROHS" }

            "*tech1" { $propName ="Tech" }

             default { continue }

        }

        $partObject | Add-Member NoteProperty $propName $part.Value

    }

    #$partsObjects += $partObject

    #$hpProduct.Parts += $partObject

    $hpProduct.Parts | Add-Member NoteProperty $partObject.PartNumber $partObject

}



### Download and parse warranty info -- Page is too messy to clean for XML casting, will just scrape with regex

$ErrorActionPreference = "Stop" #Needed so script won't continue if the web server returns an error

$htData = $htClient.DownloadString("$($hpWarrantyQueryUrl)&sn=$($serialNumber)&pn=$($productNumber)")

$ErrorActionPreference = "Continue"



$warranty = @()

$htData = $htData -replace "<br>"

while ($htData -match "<td[^>]*>\s*([\w\s:]*)\s*</td>\s*<td[^>]*>\s*(\d{1,2} \w{3} \d{4})\s*</td>\s*<td[^>]*>\s*(\d{1,2} \w{3} \d{4})\s*</td>" ) {

    $warranty += $Matches[1..3]

    $htData = $htData.Replace($Matches[0],1)

}

$warranty = $warranty -replace "wty: |HWM |HP |HW |Maintenance |Support |for "





### Display data

"-"*90



"Serial Number:`t$($serialNumber)"

"Product Number:`t$($productNumber)"

"Description:`t$($productDescr)"



"-"*90



"Warranty:"

$i = 0

while ( $i -lt $warranty.Length ){

  "$($warranty[$i])`t`tStart: $($warranty[$i+1])`t`tEnd: $($warranty[$i+2])"

  $i += 3

}



"-"*90



"Available Parts: $($orderableParts.Length)"

"-"*90

$orderableParts

"-"*90


Contact
ViewVC Help
Powered by ViewVC 1.0.4