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

View of /Get-HpProductInfo.ps1

Parent Directory Parent Directory | Revision Log Revision Log


Revision 33 - (download) (annotate)
Wed Aug 13 05:51:05 2014 UTC (9 years, 8 months ago) by ian
File size: 63844 byte(s)
Constant variables to allow changing the target country;
If a serial number matches products for more than one region now instead of errors, it will automatically select the appropriate product based on the country constant variables;
Bug: When there are multiple matching products, it will output a bunch of errors on the first query for that serial number.  Subsequent queries will pull data that was cached and will display fine.
þÿ<#



.NOTES

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

 Get-HpProductInfo.ps1 v0.9

 

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:

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

 -Generate a proper object (this will allow tab completion and easier programmatic use)

 -Filter out more irrelevant parts by country code suffix on the PN. ex: -BG1 = Swiss

 -Fix: When there are multiple matching products, it will output a bunch of errors on the first query for that serial number.  Subsequent queries will pull data that was cached and will display fine.



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, Position = 0, ValueFromPipeline= $True )]

    [Alias( "SN" )]

    [String[]]

    $SerialNumber,



    #Search string for parts listing.

    [Parameter( Position = 1 )]

    [Alias( "Part" )]

    $PartQuery,

    

    #Output an object instead of an plain text.

    [Switch]

    [Alias( "Object" )]

    $OutputObject,



    #Purge cash for supplied SN(s) and fetch fresh data

    [Switch]

    [Alias( "Purge" )]

    $Refresh

)





BEGIN {

    Set-StrictMode -Version Latest

    IF ( $Script:PSBoundParameters.ContainsKey("Debug") ) { $DebugPreference = "Continue" } ### For some reason I was getting first 3 debug lines output in the Process block even with using -Debug, but none afterwards



    ###### Set Constants

    IF ( -not ( Test-Path Variable:\\fullRegionName ) ) { #This prevents errors from being generated when running from ISE

        Set-Variable fullRegionName -Option Constant -value "United States"

        Set-Variable abbrRegionName -Option Constant -Value "US"

        Set-Variable regionSuffix -Option Constant -Value "#ABA"

        Set-Variable productObjectVersion -option Constant -value 0.4

        Set-Variable partSurferQueryUrl -option Constant -value "http://partsurfer.hp.com/Search.aspx?searchText="

        Set-Variable hpWarrantyBaseUrl -option Constant -value "https://h20565.www2.hp.com"

        Set-Variable hpWarrantyStartPath -option Constant -value "/portal/site/hpsc/public/wc/home/"

        Set-Variable hpWarrantyQueryUrl -option Constant -value "https://h20566.www2.hp.com/portal/site/hpsc/template.PAGE/action.process/public/wc/home/?javax.portlet.action=true&javax.portlet.sync=d549c6d9a9acda7f8405adb432a15c01&javax.portlet.tpst=c4efedb99acca32ea782977bb053ce01&javax.portlet.prp_c4efedb99acca32ea782977bb053ce01=wsrp-interactionState%3Daction%253Dfind&javax.portlet.begCacheTok=com.vignette.cachetoken&javax.portlet.endCacheTok=com.vignette.cachetoken"

        Set-Variable cacheDir -option Constant -value (Join-Path $env:APPDATA "HpProductInfo_Cache")

        Set-Variable maxCacheAge -option Constant -value 90 #In Days

    }



    ###### Prep

    IF ( !( Test-Path $cacheDir ) ){ $null = New-Item -Type "Directory" -Path $cacheDir }



### This was causing issues with other PowerShell scripts.  It will remain disabled till I learn to fix it across all versions of PowerShell or I no longer need to support PS 1.0.

<#    ###### Default display property set #Maybe this will be added back in future, not really necessary anyway

    $objectTemplateFile = Join-Path $cacheDir "HpProductObjectTemplate_v$($productObjectVersion).ps1xml"

    IF ( !( Test-Path $objectTemplateFile ) ) {

        $template = "<?xml version='1.0' encoding='utf-8' ?>"

        $template += "<Types><Type><Name>System.Management.Automation.PSCustomObject</Name><Members><MemberSet>"

        $template += "<Name>PSStandardMembers</Name><Members><PropertySet><Name>DefaultDisplayPropertySet</Name><ReferencedProperties>"

        $template += "<Name>ProductNumber</Name>"

        $template += "<Name>SerialNumber</Name>"

        $template += "<Name>Description</Name>"

        $template += "<Name>WarrantyOnsite</Name>"

        $template += "<Name>Parts</Name>"

        $template += "</ReferencedProperties></PropertySet></Members></MemberSet></Members></Type></Types>"

        Out-File $objectTemplateFile -Encoding "UTF8" -InputObject $template -Force

    }

    IF ( $PSVersionTable.PSVersion.Major -gt 2 ) {

        Update-TypeData $objectTemplateFile

    }

    elseif ( ! ( $host.Runspace.RunspaceConfiguration.Types | ? { $_.FileName -eq $objectTemplateFile } ) ) {

        Update-TypeData $objectTemplateFile

    }

#>

}



PROCESS {

    Function CleanHtml($htData) {

        RETURN $htData -replace "(\r|\f|\n)*" -replace "\t", " " -replace "  " -replace "> <", "><" -replace "&nbsp;" -replace "<a .*?>" -replace "</a>"

    }

    Foreach ($SerialNumber in $SerialNumber) {

        $SerialNumber = $SerialNumber.Trim().ToUpper()



        Write-Debug ">> Check cache for XML copy of data"

        $useCache = $false

        IF ( $cacheHit = ls $cacheDir | ? { $_.Name -like "$($SerialNumber)_*" } ) {

            Write-Debug "Cache Hit!!! ($cacheHit)"

            $useCache = $true

            IF ( $Refresh ) {

                $useCache = $false

            }

            elseif ( $cacheHit -notlike "*_v$($productObjectVersion).xml" ) {

                Write-Debug "Version Mismatch; Deleting... :-("

                $useCache = $false

            }

            elseif ( ( Get-Date ) -gt $cacheHit.CreationTime.AddDays(90) ) {

                Write-Debug "Stale Cache; Deleting... :-("

                $useCache = $false

            }



            IF ( ! $useCache ) { Remove-Item ( Join-Path $cacheDir $cacheHit ) }

        }

        Write-Debug "Using Cache: $($useCache)"

        Write-Debug "<< End Check Cache"





        function downloadProductData () {

            Write-Debug "Load initial warranty lookup page to get ID cookies, run ahead of time for the session to settle on the server or w/e"

            $cookieContainer = New-Object System.Net.CookieContainer



            [net.httpWebRequest] $webReq = [net.webRequest]::create("$($hpWarrantyBaseURL)$($hpWarrantyStartPath)")

            $webReq.CookieContainer = $cookieContainer

            [net.httpWebResponse] $webResp = $webReq.GetResponse()

            $strRdr = New-Object IO.StreamReader($webResp.GetResponseStream())

            $htData = $strRdr.ReadToEnd()

            $webResp.Close()





            Write-Debug "Parse out POST action"

            $null = $htData -match "<form .*? name=`"warrantyCheck`" .*? action=`"([^`"]*)`""

            $hpWarrantyQueryPath = $Matches[1]





            Write-Debug "Create WebClient and cookie needed for PartSurfer"

            $htClient = New-Object System.Net.Webclient

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

            $htClient.Headers.Set([System.Net.HttpRequestHeader]::Cookie, "Country=$($fullRegionName)")



            Write-Debug "/!\Begin critical section/!\ Any errors here break the entire script."

            $ErrorActionPreference = "Stop"



            <#

            IF ( $Script:PSBoundParameters.ContainsKey("Debug") ) {

                Write-Debug "Debugging is enabled, using cached raw html if available"



                #IF ( ls $cacheDir | ? { $_.Name -eq "$($SerialNumber).raw.html" } ) {

                IF ( Test-Path ( Join-Path $cacheDir "$($SerialNumber).raw.html" ) ) {

                    Write-Debug "Raw HTML read from cache"

                    $htData = Get-Content (Join-Path $cacheDir "$($SerialNumber).raw.html")

                }

                ELSE {

                #>

                    Write-Debug "Downloading PartSurfer HTML data"

                    #$htData = $htClient.DownloadString("$($partSurferQueryUrl)$($SerialNumber)")

                    [net.httpWebRequest] $webReq = [net.webRequest]::create("$($partSurferQueryUrl)$($SerialNumber)")

                    ###$webReq.CookieContainer = $cookieContainer

                    [net.httpWebResponse] $webResp = $webReq.GetResponse()

                    $strRdr = New-Object IO.StreamReader($webResp.GetResponseStream())

                    $htData = $strRdr.ReadToEnd()

                    $webResp.Close()



                    $htData = CleanHtml( $htData )



                    Write-Debug "Raw HTML written to cache"

                    Set-Content (Join-Path $cacheDir "$($SerialNumber).raw.html") $htData

                <#

                }

            }

            ELSE {

                Write-Debug "Downloading PartSurfer HTML data"

                #$htData = $htClient.DownloadString("$($partSurferQueryUrl)$($SerialNumber)")

                [net.httpWebRequest] $webReq = [net.webRequest]::create("$($partSurferQueryUrl)$($SerialNumber)")

                $webReq.CookieContainer = $cookieContainer

                [net.httpWebResponse] $webResp = $webReq.GetResponse()

                $strRdr = New-Object IO.StreamReader($webResp.GetResponseStream())

                $htData = $strRdr.ReadToEnd()

                $webResp.Close()



                Write-Debug "Clean line breaks, tabs, multiple spaces, and blank space between tags"

                $htData = CleanHtml( $htData )

            } #commented to match top part of if block commented out#>

           

            Write-Debug "Check if page is asking to choose which region the product is from due to multiple serial number matches."

            IF ( $htData -match 'type="radio"' ) {

                Write-Debug "Attempting to select the correct product based on region suffix."

                $fullSku = ""

                IF ( $Script:PSBoundParameters.ContainsKey("Debug") ) {

                    Write-Debug "Debugging is enabled, renaming original cache file to ...please.select.raw.html."

                    Move-Item -Force ( Join-Path $cacheDir "$($SerialNumber).raw.html" ) ( Join-Path $cacheDir "$($SerialNumber).please.select.raw.html" )

                }



                $htData -match "`".......$($regionSuffix)`""

                IF ( $Matches.Count -eq 1 ) {

                    $fullSku = $Matches[0] -replace '"', ""

                    $partSurferRetries = 0

                    DO {

                        $partSurferRetries++

                        Write-Debug "Create POST request to search PartSurfer again with SKU ($($fullSku)). Attempt# $($partSurferRetries)"

                       # Sleep 45 



                        [net.httpWebRequest] $webReq = [net.webRequest]::create("$($partSurferQueryUrl)$($SerialNumber)")

                        $webReq.CookieContainer = $cookieContainer

                        $webReq.Method = "POST"

                        $webReq.Host = "partsurfer.hp.com"

                        $webReq.Referer = "http://partsurfer.hp.com/Search.aspx?SearchText=$($SerialNumber)"





                        Write-Debug "Looking for (strikeout non-blank) all (blank or not) form fields to include in POST header..."

                        $postData = ""

                        $postInputs = Select-String "<input.*?>" -inputObject $htData -AllMatches

                        $postInputs.Matches | ? { $_ -notmatch ".*(submit|image|radio).*" } | % {

                          $null = $_ -match ".*?name=`"(.*?)`".*?>"

                          $newData = "$($Matches[1])="



                          IF ( $_ -match ".*?value=`"(.*?)`".*?>" ) {

                            Write-Debug "$($newData) `"$( IF ( $Matches[1].Length -gt 65 ) { "$($Matches[1].Substring(0,55))...(truncated)" } ELSE { $Matches[1] } )`""

                            $newData += $Matches[1]

                          }



                          $postData += "$($newData)&"

                        }

                        Write-Debug "ctl00`$BodyContentPlaceHolder`$radProd = $($fullSku)"

                        $postData += "ctl00`$BodyContentPlaceHolder`$radProd=$($fullSku)"

                        #Write-Debug "`$postData=`n$PostData"



                        #$postData = "&__EVENTTARGET="

                        #$postData += "&__EVENTARGUMENT="

                        #$postData += "&__VIEWSTATE=/wEPDwUKMTI2NzMyMTI0OA9kFgJmD2QWAmYPZBYGZg8WAh4Fd2lkdGgFBjE0MDBweGQCEA9kFggCDw9kFgJmD2QWAgIBD2QWAgIDDw8WBB4EVGV4dAUTUHJvZHVjdCBJbmZvcm1hdGlvbh4HVmlzaWJsZWdkZAIQD2QWAmYPZBYCAgEPDxYKHglGb3JlQ29sb3IKex8BBRVIUCBBU1DigJlzIGNsaWNrIGhlcmUeC05hdmlnYXRlVXJsBQEjHghDc3NDbGFzcwUKZW5hYmxlTGluax4EXyFTQgIGZGQCEg8QDxYGHg1EYXRhVGV4dEZpZWxkBQxDT1VOVFJZX05BTUUeDkRhdGFWYWx1ZUZpZWxkBQxDT1VOVFJZX0NPREUeC18hRGF0YUJvdW5kZxYEHghPbkNoYW5nZQUNZXJhc2VDb29raWUoKR4HT25Gb2N1cwUQY291bnRyeU9uRm9jdXMoKRAVggELU0VMRUNUIE9ORT4HQWxiYW5pYQdBbGdlcmlhCEFuZ3VpbGxhG0FudGlndWEgYW5kIEJhcmJ1ZGEgSXNsYW5kcwlBcmdlbnRpbmEFQXJ1YmEJQXVzdHJhbGlhB0F1c3RyaWEKQXplcmJhaWphbgdCYWhhbWFzB0JhaHJhaW4IQmFyYmFkb3MHQmVsYXJ1cwdCZWxnaXVtBkJlbGl6ZQdCZXJtdWRhB0JvbGl2aWESQm9zbmlhLUhlcnplZ292aW5hBkJyYXppbAhCdWxnYXJpYQZDYW5hZGEcQ2FudG9uIGFuZCBFbmRlcmJ1cnkgSXNsYW5kcw5DYXltYW4gSXNsYW5kcwVDaGlsZQVDaGluYQhDb2xvbWJpYQVDb25nbwpDb3N0YSBSaWNhB0Nyb2F0aWEGQ3lwcnVzDkN6ZWNoIFJlcHVibGljB0Rlbm1hcmsIRG9taW5pY2ESRG9taW5pY2FuIFJlcHVibGljDkVhc3Rlcm4gRXVyb3BlB0VjdWFkb3IFRWd5cHQLRWwgU2FsdmFkb3IGRXVyb3BlEEZhbGtsYW5kIElzbGFuZHMHRmlubGFuZAZGcmFuY2UHR2VybWFueQZHcmVlY2UHR3JlbmFkYQRHdWFtCUd1YXRlbWFsYQZHdXlhbmEFSGFpdGkISG9uZHVyYXMJSG9uZyBLb25nB0h1bmdhcnkFSW5kaWEJSW5kb25lc2lhBElyYXEHSXJlbGFuZAZJc3JhZWwFSXRhbHkHSmFtYWljYQVKYXBhbgZKb3JkYW4KS2F6YWtoc3RhbgVLZW55YQZLdXdhaXQNTGF0aW4gQW1lcmljYQdMZWJhbm9uCkx1eGVtYm91cmcJTWFjZWRvbmlhCE1hbGF5c2lhDk1hbHRhIGFuZCBHb3pvBk1leGljbw1NaWR3YXkgSXNsYW5kB01vbGRvdmEGTW9uYWNvCk1vbnRlbmVncm8KTW9udHNlcnJhdAdNb3JvY2NvC05ldGhlcmxhbmRzFE5ldGhlcmxhbmRzIEFudGlsbGVzC05ldyBaZWFsYW5kCU5pY2FyYWd1YQdOaWdlcmlhBk5vcndheQRPbWFuBlBhbmFtYQhQYXJhZ3VheQRQZXJ1C1BoaWxpcHBpbmVzBlBvbGFuZAhQb3J0dWdhbAtQdWVydG8gUmljbwVRYXRhchFSZXB1YmxpYyBvZiBZZW1lbgdSb21hbmlhBlJ1c3NpYQtTYWludCBMdWNpYQxTYXVkaSBBcmFiaWEGU2VyYmlhCVNpbmdhcG9yZQ9TbG92YWsgUmVwdWJsaWMIU2xvdmVuaWEMU291dGggQWZyaWNhC1NvdXRoIEtvcmVhBVNwYWluDVN0IEJhcnRoZWxlbXkJU3QgTWFydGluEVN0LiBLaXR0cyAtIE5ldmlzHlN0LiBWaW5jZW50IGFuZCB0aGUgR3JlbmFkaW5lcwhTdXJpbmFtZQZTd2VkZW4LU3dpdHplcmxhbmQGVGFpd2FuCFRoYWlsYW5kE1RyaW5pZGFkIGFuZCBUb2JhZ28HVHVuaXNpYQZUdXJrZXkUVHVya3MgYW5kIENhaWNvcyBJc2wZVVMgTWlub3IgT3V0bHlpbmcgSXNsYW5kcwdVa3JhaW5lFFVuaXRlZCBBcmFiIEVtaXJhdGVzDlVuaXRlZCBLaW5nZG9tDVVuaXRlZCBTdGF0ZXMHVXJ1Z3VheQlWZW5lenVlbGEHVmlldG5hbRhWaXJnaW4gSXNsYW5kcyBvZiB0aGUgVVMXVmlyZ2luIElzbGFuZHMsIEJyaXRpc2gLV2FrZSBJc2xhbmQKWXVnb3NsYXZpYRWCAQtTRUxFQ1QgT05FPgJBTAJEWgJBSQJBRwJBUgJBVwJBVQJBVAJBWgJCUwJCSAJCQgJCWQJCRQJCWgJCTQJCTwJCQQJCUgJCRwJDQQJDVAJLWQJDTAJDTgJDTwJDRwJDUgJIUgJDWQJDWgJESwJETQJETwJFRQJFQwJFRwJTVgJFVQJGSwJGSQJGUgJERQJHUgJHRAJHVQJHVAJHWQJIVAJITgJISwJIVQJJTgJJRAJJUQJJRQJJTAJJVAJKTQJKUAJKTwJLWgJLRQJLVwJMQQJMQgJMVQJNSwJNWQJNVAJNWAJNSQJNRAJNQwJNRQJNUwJNQQJOTAJBTgJOWgJOSQJORwJOTwJPTQJQQQJQWQJQRQJQSAJQTAJQVAJQUgJRQQJZRQJSTwJSVQJMQwJTQQJSUwJTRwJTSwJTSQJaQQJLUgJFUwJCTAJNRgJLTgJWQwJTUgJTRQJDSAJUVwJUSAJUVAJUTgJUUgJUQwJVTQJVQQJBRQJHQgJVUwJVWQJWRQJWTgJWSQJWRwJXSwJZVRQrA4IBZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2RkAhgPZBYEZg9kFg4CAQ9kFgJmD2QWBAIFDw9kFgIeB09uQ2xpY2sFHmphdmFzY3JpcHQ6Y2hlY2tDb3VudHJ5KGV2ZW50KWQCCw9kFgICAw8WAh4Fc3R5bGUFDGNvbG9yOmJsYWNrO2QCBw8WAh8CaGQCCQ8WAh8CZxYKZg8WAh8CZxYCZg9kFgQCAQ8PFgQfAQUPU2VyaWFsIE51bWJlciA6HwJnZGQCAw8PFgIfAQUKQ05VMzQ5QkRURGRkAgEPFgIfAmgWAmYPZBYCAgEPDxYCHwFlZGQCAg8WAh8CZxYCZg8WAh8CaBYCAgEPDxYCHwFlZGQCAw9kFgJmD2QWBAIBDw8WAh8CaGRkAgMPDxYCHwJoZGQCBA9kFgJmD2QWAgIBDw8WBB8BBR8qIFBSRUxJTUlOQVJZIFVORU5IQU5DRUQgREFUQSAqHwJoZGQCDQ8WAh8CaGQCDw9kFgICAw88KwANAgAPFgQfCWceC18hSXRlbUNvdW50ZmQMFCsAAGQCEQ9kFgYCAQ8WAh4FY2xhc3NlZAIDDxYCHw8FLmpzX3RhYl90cmlnZ2VyIHRhYl90cmlnZ2VyIGN1cnJlbnRfZnN0IGN1cnJlbnRkAgUPZBYEZg9kFgYCAQ8WAh8NBQ1kaXNwbGF5OiBub25lFgICAQ9kFg4CAQ8QDxYCHwlnZBAVABUAFCsDABYAZAIDDxAPFgIeB0NoZWNrZWRoZGRkZAIFDxAPFgIfEGhkZGRkAgcPEA8WAh8JZ2QQFQAVABQrAwAWAGQCCQ8QZGQWAWZkAgsPEGRkFgBkAg0PEA8WBB4FV2lkdGgbAAAAAADAYkABAAAAHwYCgAJkEBUAFQAUKwMAFgBkAgIPZBYCAgEPEGRkFgBkAgUPDxYCHwFlZGQCAQ9kFgYCBw9kFgJmDxYCHw0FDiBkaXNwbGF5OiBub25lFgICAQ9kFgoCAQ8QDxYCHwlnZBAVABUAFCsDABYAZAIDDxAPFgIfEGhkZGRkAgUPEGRkFgFmZAIHDxBkZBYAZAINDxAPFgQfERsAAAAAAMBiQAEAAAAfBgKAAmQQFQAVABQrAwAWAGQCCQ9kFgICAQ88KwANAQAPFgQfCWcfDmZkZAILD2QWAgIBDzwrAA0BAA8WBB8JZx8OZmRkAhMPDxYCHwJnZBYEAgMPDxYCHwEFCkNOVTM0OUJEVERkZAIFDxAPFgIfCWdkEBUCJ0M3TTMxVVAgLSBFODQ3MHBVNTMzNk1NTjE4ME1JQzA4TmVTIEFMTCpDN00zMVVQI0FCQSAtIEU4NDcwcFU1MzM2TU1OMTgwTUlDMDhOZVMgVVMVAgdDN00zMVVQC0M3TTMxVVAjQUJBFCsDAmdnZGQCAQ9kFgICAQ9kFgJmD2QWCgIDDxQrAAJkZGQCBQ8UKwACZGRkAgcPPCsACQEADxYCHg1OZXZlckV4cGFuZGVkZ2RkAgoPFCsAAmRkZAIMDxQrAAJkZGQCEw8PFgQfAQUZRmVlZGJhY2sgdG8gSFAgUGFydFN1cmZlch4QQ2F1c2VzVmFsaWRhdGlvbmhkZBgKBShjdGwwMCRCb2R5Q29udGVudFBsYWNlSG9sZGVyJFByb2R1Y3RMaXN0D2dkBSdjdGwwMCRCb2R5Q29udGVudFBsYWNlSG9sZGVyJE11bHRpVmlldzEPD2RmZAUpY3RsMDAkQm9keUNvbnRlbnRQbGFjZUhvbGRlciRncmlkU3BhcmVCT00PPCsACgEIZmQFKmN0bDAwJEJvZHlDb250ZW50UGxhY2VIb2xkZXIkSGllcmFyY2h5TGlzdA9nZAUmY3RsMDAkQm9keUNvbnRlbnRQbGFjZUhvbGRlciRndkdlbmVyYWwPPCsACgIGFQELUEFSVF9OVU1CRVIIZmQFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYCBSdjdGwwMCRCb2R5Q29udGVudFBsYWNlSG9sZGVyJFNDYXJ0JEhvbWUFJ2N0bDAwJEJvZHlDb250ZW50UGxhY2VIb2xkZXIkU0NhcnQkY2FydAUtY3RsMDAkQm9keUNvbnRlbnRQbGFjZUhvbGRlciRUb3BIaWVyYXJjaHlMaXN0D2dkBSdjdGwwMCRCb2R5Q29udGVudFBsYWNlSG9sZGVyJGdyaWRDT01CT00PPCsACgEIZmQFLWN0bDAwJEJvZHlDb250ZW50UGxhY2VIb2xkZXIkSGllcmFyY2h5VG9wTGlzdA9nZAUnY3RsMDAkQm9keUNvbnRlbnRQbGFjZUhvbGRlciRNdWx0aVZpZXcyDw9kAgFke9jF3YWEcTMlFAPpXsH4fUOKOmw"

                        #$postData += "&__PREVIOUSPAGE=uel1OJqwRzAzE7TWcjP1qs5L_mZbu5sqD7lqKYLrWJW8jPPUiBIirA7ZvP81"

                        <#

                        $postData += "ctl00`$BodyContentPlaceHolder`$hType="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hCountry="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnPSP="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnBuyPart="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnPSPType="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnPartNo="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnFileName="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnSearchText=$($SerialNumber)"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hHPPSFlag=Y"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnstrType=SERIAL"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnMULTI_PART="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdnAddPartsFlag=N"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$txtOutlet_id="

                        $postData += "&ctl00`$BodyContentPlaceHolder`$ddlCountry=$($abbrRegionName)"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hdDIVButton=0"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$SearchText`$TextBox1=$($SerialNumber)"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$radProd=$($fullSku)"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$btnProdSubmit= View Selected Product Details "

                        $postData += "&ctl00`$BodyContentPlaceHolder`$hiddenEnhancedStatus="

                        #>

                        

                        #$postData += "&ctl00`$BodyContentPlaceHolder`$SearchText`$TextBox1=$($SerialNumber)"

                        $postData += "&ctl00`$BodyContentPlaceHolder`$btnProdSubmit= View Selected Product Details "

                        $postData += "&ctl00`$BodyContentPlaceHolder`$ddlCountry=$($abbrRegionName)"







                        Write-Debug "Post header complete.  Submitting..."

                        $postBuffer = [Text.Encoding]::Ascii.GetBytes($postData)

                        $webReq.ContentLength = $postBuffer.Length

                        $webReq.ContentType = "application/x-www-form-urlencoded"

                        $reqStr = $webReq.GetRequestStream()

                        $reqStr.Write( $postBuffer, 0, $postBuffer.Length)

                        $reqStr.Flush()

                        $reqStr.Close()



                        [net.httpWebResponse] $webResp = $webReq.GetResponse()

                        $strRdr = New-Object IO.StreamReader($webResp.GetResponseStream())

                        $htData = $strRdr.ReadToEnd()

                        $webResp.Close()



                        $htData = CleanHtml( $htData )



                        IF ( $Script:PSBoundParameters.ContainsKey("Debug") ) {

                            Write-Debug "Raw HTML written to cache"

                            Set-Content (Join-Path $cacheDir "$($SerialNumber).raw.html") $htData

                        }

                    } WHILE ( $htData -match 'type="radio"' )

                }

                ELSE { Write-Error "Multiple serial# matches, and we weren't able to determine the correct one." }

                <#Gets posted back to the same query URL

                ctl00$BodyContentPlaceHolder$hdnSearchText:"CNU349BDTD"

                ctl00$BodyContentPlaceHolder$hHPPSFlag:"Y"

                ctl00$BodyContentPlaceHolder$hdnstrType:"SERIAL"

                ctl00$BodyContentPlaceHolder$hdnAddPartsFlag:"N"

                ctl00$BodyContentPlaceHolder$ddlCountry:"US"

                ctl00$BodyContentPlaceHolder$hdDIVButton:"0"

                ctl00$BodyContentPlaceHolder$SearchText$TextBox1:"CNU349BDTD"

                ctl00$BodyContentPlaceHolder$radProd:"C7M31UP#ABA"

                ctl00$BodyContentPlaceHolder$btnProdSubmit:"+View+Selected+Product+Details+"

                #>

                

            }



            Write-Debug "Create psObject representing the product"

            $hpProduct = New-Object psObject



            Write-Debug "Load generic sku data into the object"

            Write-Debug "Load SerialNumber"

            $hpProduct | Add-Member NoteProperty SerialNumber $SerialNumber



            Write-Debug "Load ProductNumber"

            $null = $htData -match "<span id=`"ctl00_BodyContentPlaceHolder_lblProductNumber`">(.*?)</span>"

            $hpProduct | Add-Member NoteProperty ProductNumber $Matches[1]



            Write-Debug "Load Description"

            $null = $htData -match "<span id=`"ctl00_BodyContentPlaceHolder_lblDescription`">(.*?)</span>"

            $hpProduct | Add-Member NoteProperty Description $Matches[1]



            $ErrorActionPreference = "Continue"

            Write-Debug "/!\End critical section/!\"







            Write-Debug "Add Spare and OEM parts to psObject (Check boxes are no longer supplied by the site to determine part availability)"

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

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



            $trMatches = Select-String "<tr class=`"[^`"]*RowStyle`">.*?</tr>" -inputObject $htData -AllMatches

            foreach ( $trMatch in $trMatches.Matches ){

                IF ( $trMatch.Value -notmatch ".*(no longer supplied|Not Available|Hebrew|Cyrillic|Greek|Arabic|Bulk|220V|- AR|- CS|- DA|- NL|- FI|- DE|- EL|- HE|- HU|- KO|- NO|- PL|- ZHCN|- ZHTW|- TH|PCID|SWID| CH | CH<|CHINARUSS).*" )

                {

                    $spanMatches = Select-String "<span.*?>(.*?)</span>" -inputObject $trMatch.Value -AllMatches

                    $partObject = New-Object psObject

                    $partObject | Add-Member NoteProperty PartNumber $spanMatches.Matches[0].Groups[1].Value

                    $partObject | Add-Member NoteProperty Description $spanMatches.Matches[1].Groups[1].Value

                    

                    $BomType = "OemParts"

                    IF ( $trMatch.Value -match ".*_gridSpareBOM_.*" ) { $BomType = "Spares" }



                    $ErrorActionPreference = "SilentlyContinue"

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

                    $ErrorActionPreference = "Continue"

                    Write-Debug "$($BomType): $($partObject.PartNumber) - $($partObject.Description)"

                }

                ELSE { Write-Debug "Discarding invalid or no longer supplied part." }

            }

            

            $warrAttempts = 0

            $trMatches = ""

            DO {

                sleep ( 15 + $warrAttempts * 3 )

                Write-Debug "Create POST request to retrieve warranty data. Attempt #$($warrAttempts)"

                [net.httpWebRequest] $webReq = [net.webRequest]::create("$($hpWarrantyBaseURL)$($hpWarrantyQueryPath)")

                $webReq.CookieContainer = $cookieContainer

                $webReq.Method = "POST"



                #$postData = "rows[0].item.serialNumber=$($SerialNumber)&rows[0].item.countryCode=US&rows[1].item.serialNumber=&rows[1].item.countryCode=US&rows[2].item.serialNumber=&rows[2].item.countryCode=US&rows[3].item.serialNumber=&rows[3].item.countryCode=US&rows[4].item.serialNumber=&rows[4].item.countryCode=US&rows[5].item.serialNumber=&rows[5].item.countryCode=US&rows[6].item.serialNumber=&rows[6].item.countryCode=US&rows[7].item.serialNumber=&rows[7].item.countryCode=US&rows[8].item.serialNumber=&rows[8].item.countryCode=US&rows[9].item.serialNumber=&rows[9].item.countryCode=US&submitButton=Submit"

                $postData = "rows[0].item.serialNumber=$($SerialNumber)&rows[0].item.countryCode=$($abbrRegionName)&rows[1].item.serialNumber=&rows[1].item.countryCode=US&rows[2].item.serialNumber=&rows[2].item.countryCode=US&rows[3].item.serialNumber=&rows[3].item.countryCode=US&rows[4].item.serialNumber=&rows[4].item.countryCode=US&rows[5].item.serialNumber=&rows[5].item.countryCode=US&rows[6].item.serialNumber=&rows[6].item.countryCode=US&rows[7].item.serialNumber=&rows[7].item.countryCode=US&rows[8].item.serialNumber=&rows[8].item.countryCode=US&rows[9].item.serialNumber=&rows[9].item.countryCode=US&submitButton=Submit"

                $postBuffer = [Text.Encoding]::Ascii.GetBytes($postData)

                $webReq.ContentLength = $postBuffer.Length

                $webReq.ContentType = "application/x-www-form-urlencoded"

                $reqStr = $webReq.GetRequestStream()

                $reqStr.Write( $postBuffer, 0, $postBuffer.Length)

                $reqStr.Flush()

                $reqStr.Close()



                [net.httpWebResponse] $webResp = $webReq.GetResponse()

                $strRdr = New-Object IO.StreamReader($webResp.GetResponseStream())

                $htData = $strRdr.ReadToEnd()

                $webResp.Close()



                $htData = CleanHtml( $htData )

                $warrAttempts++

                $trMatches = Select-String "<tr class='hpui-(normal|alternate)-row'.*?</tr>" -inputObject $htData -AllMatches

            }

            WHILE ( $warrAttempts -lt 6 -and -not $trMatches )



            Write-Debug "Parse warranty data and add to the object"

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

            

            FOREACH ( $trMatch in $trMatches.Matches ) {

                $tdMatches = Select-String "<td((?!rowspan|color).)*?</td>" -inputObject $trMatch -AllMatches

  

                $warrData = $tdMatches.Matches | % {

                    $_.value -replace "</?td[^>]*>" -replace "Wty: " -replace "HP " -replace "HW Maintenance ", "HWM " -replace "Support ?(for )?"

                }



                IF ( $warrData[1].Length -or $warrData[2].Length ) {

                    $warrObject = New-Object psObject

                    $warrObject | Add-Member NoteProperty Start ( '{0:yyyy-MM-dd}' -f ( Get-Date $warrData[1] ) )

                    $warrObject | Add-Member NoteProperty End ( '{0:yyyy-MM-dd}' -f ( Get-Date $warrData[2] ) )

                    $hpProduct.Warranties | Add-Member NoteProperty $warrData[0] $warrObject

                    Write-Debug "Added Warranty: $($warrData[0]) - $( '{0:yyyy-MM-dd}' -f ( Get-Date $warrData[1] ) ) to $( '{0:yyyy-MM-dd}' -f ( Get-Date $warrData[2] ) )"

                }

                ELSE { $hpProduct.Warranties | Add-Member NoteProperty $warrData[0] "" }

            }

          



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

            $hpProduct | Add-Member NoteProperty __productObjectVersion $productObjectVersion



            $hpProduct | Export-Clixml (Join-Path $cacheDir "$($hpProduct.SerialNumber)_$($hpProduct.ProductNumber)_v$($productObjectVersion).xml")

            RETURN $hpProduct

        }





        #Import line is potentially error prone, make it more specific later on

        IF ( $useCache ) { $hpProduct = Import-Clixml ( Join-Path $cacheDir "$($SerialNumber)_*" ) }

        ELSE { $hpProduct = downloadProductData }





        IF ( $OutputObject ) {

            $hpProduct

        }

        ELSE {

            $lineLen = 75



            "%ˆ" * $lineLen



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

            "Product Number:`t$($hpProduct.ProductNumber -replace '#ABA' )"

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

            ""

            



            $partsTxt = @()

            $warranties = $hpProduct.Warranties | get-member -MemberType "NoteProperty"

            foreach ( $warranty in $warranties | % { $_.Name } ) {

                IF ( ($hpProduct.Warranties.$warranty | Get-Member | % { $_.Name } ) -contains "Start" ) {

                    $partsTxt += "$($warranty)  `t$($hpProduct.Warranties.$warranty.Start)`t$($hpProduct.Warranties.$warranty.End)"

                }

                ELSE { $partsTxt += $warranty }

            }

            "Warranties: $($partsTxt.Length)"

            "%" * $lineLen

            $partsTxt



            ""

            $parts = $hpProduct.OemParts | get-member -MemberType "NoteProperty"

            $partsTxt = @()

            foreach ( $part in $parts | % { $_.Name } ) {

                IF ( $PartQuery ) {

                    IF ( $hpProduct.OemParts.$part.Description -match ".*$($PartQuery).*" ) {

                        $partsTxt += "$($hpProduct.OemParts.$part.PartNumber) - $($hpProduct.OemParts.$part.Description)"

                    }

                }

                ELSE { $partsTxt += "$($hpProduct.OemParts.$part.PartNumber) - $($hpProduct.OemParts.$part.Description)" }

            }

            "OEM Parts$(IF ( $PartQuery ) {" matching query '$($PartQuery)'"}): $($partsTxt.Length)"

            "%" * $lineLen

            $partsTxt





            ""

            $parts = $hpProduct.Spares | get-member -MemberType "NoteProperty"

            $partsTxt = @()

            foreach ( $part in $parts | % { $_.Name } ) {

                IF ( $PartQuery ) {

                    IF ( $hpProduct.Spares.$part.Description -match ".*$($PartQuery).*" ) {

                        $partsTxt += "$($hpProduct.Spares.$part.PartNumber) - $($hpProduct.Spares.$part.Description)"

                    }

                }

                ELSE { $partsTxt += "$($hpProduct.Spares.$part.PartNumber) - $($hpProduct.Spares.$part.Description)" }  

            }

            "Spares$(IF ( $PartQuery ) {" matching query '$($PartQuery)'"}): $($partsTxt.Length)"

            "%" * $lineLen

            $partsTxt

            

            "%ˆ"*$lineLen

        }

    }

}

Contact
ViewVC Help
Powered by ViewVC 1.0.4