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

View of /Get-HpProductInfo.ps1

Parent Directory Parent Directory | Revision Log Revision Log


Revision 13 - (download) (annotate)
Mon Aug 26 05:38:55 2013 UTC (10 years, 8 months ago) by ian
File size: 13654 byte(s)
proper param and info markup for using the Get-Help;
now returns plain text or supply the OjbectOutput switch to return an object;
I realized the implementation of nested objects is not proper, will do more research and try to fix later;
þÿ<#

.NOTES

 Written by Ian Cammarata  http://ian.cammarata.us

 Get-HpProductInfo.ps1 v0.2

 

This will probably only work for products sold in the U.S. 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)

 -Cache objects to an XML file 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

SNs for testing: CND120CJH0, CNU305BP9N, CNFKF52058, JPBCD3R1H3





.SYNOPSIS

Query by SN to retreive HP product info from PartSufer and HP Business warranty lookup.





.EXAMPLE

PS> Get-HpProductInfo JPBCD3R1H3



#>



param(

    #The serial number to query

    [Parameter( Mandatory = $True )]

    [String]$lookupSn,

    

    #Output plain text instead of an object

    [Switch]$ObjectOutput

)

#$lookupSn = "JPBCD3R1H3" uncomment for testing in ISE



Set-StrictMode -Version Latest



$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



$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 }



$skuDataHash = @{}

$partSurferXml.SelectNodes("//span") | ? { $_.id -like "*lbl*" -and $_.id -notlike "*BOM*" -and $_.id -notlike "*text*" } |

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



$ErrorActionPreference = "Continue"





### Create psObject and start adding to it

$hpProduct = New-Object psObject

# Default display property set

<# Broken in PS 2.0; I may implement the fix @ http://stackoverflow.com/questions/1369542/can-you-set-an-objects-defaultdisplaypropertyset-in-a-powershell-v2-script

$defaultPropArr = @( 'ProductNumber', 'SerialNumber', 'Description', 'WarrantyOnsite', 'Parts' )

$defaultPropObj = New-Object System.Management.Automation.PSPropertySet( 'DefaultDisplayPropertySet', [string[]]$defaultPropArr )

$psStandardMembers = [System.Management.Automation.PSMemberInfo[]]@( $defaultDisplayProperties )

$hpProduct | Add-Member MemberSet PSStandardMembers $psStandardMembers -force

#>



foreach ( $skuDatum in $skuDataHash.GetEnumerator() ){

    $propName = ""

    switch -wildcard ($skuDatum.Name) {

        "*SerialNumber" { $propName ="SerialNumber" }

        "*ProductNumber" { $propName ="ProductNumber" }

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

    }

    if ( $propName ) { $hpProduct | Add-Member NoteProperty $propName $skuDatum.Value }

}

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





### 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=$($hpProduct.SerialNumber)&pn=$($hpProduct.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| "



### Add warranty data to psObject

$i = 0

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

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

  $hpProduct | Add-Member NoteProperty "Warranty$($warranty[$i])" @{ Start = ( Get-Date $warranty[$i+1] ); End = ( Get-Date $warranty[$i+2] ) } -force

  $i += 3

}





### Add orderable parts to psObject

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 = ""

        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" }

        }

        if ( $propName ) { $partObject | Add-Member NoteProperty $propName $part.Value }

    }

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

}





$hpProduct | Add-Member NoteProperty __QueryDate (Get-Date)





### Cleanup (probably not necessary?)

#Remove-Variable "a", "b"



if ( $ObjectOutput ) {

    $hpProduct

}

Else {

    "-"*90



    "Serial Number:`t$($hpProduct.SerialNumber)"

    "Product Number:`t$($hpProduct.ProductNumber)"

    "Description:`t$($hpProduct.Description)"



    "-"*90



    "Warranty:"

    foreach ( $warrantyItem in $hpProduct | Get-Member | ? { $_.Name -like "Warranty*" } | % { $_.Name } ) {

      "$($warrantyItem):"

      "     Start: $($hpProduct.$warrantyItem.Start)     End: $($hpProduct.$warrantyItem.End)"

    }



    #"-"*90

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

    "-"*90

    foreach ( $part in $hpProduct.Parts | Get-Member | ? { $_.MemberType -eq "NoteProperty" } | % { $_.Name } ) {

        "$($hpProduct.Parts.$part.PartNumber) - $($hpProduct.Parts.$part.Description)"

    }

    "-"*90

}

Contact
ViewVC Help
Powered by ViewVC 1.0.4