HP server warranty via the ISEE API

TL;DR: Here’s a simple proof of concept program to look up HP server warranty details via the HP ISEE API. That’s right: no more web scraping.

If you’ve ever tried to look up warranty details for an HP server, you’ve probably come across some of these:

  1. http://h20566.www2.hp.com/portal/site/hpsc/public/wc/home/
  2. http://h20000.www2.hp.com/bizsupport/TechSupport/WarrantyLookup.jsp
  3. http://h10025.www1.hp.com/ewfrf/wc/weInput

For anything other than a couple of servers, these are useless. Also:

  • The last one is for non-server products. I wish it clearly said so.
  • Two different UIs for warranty lookup. No link between them.
  • One requires the product number for 10-digit serials, while the other does not. I’m guessing that’s due to duplicate serials coming from various aquisitions over the years.
  • The output data varies significantly. The first one is definitely the most interesting.

So you sit there and copy-paste serials and product numbers while your life drains away at every click, and then you get the brilliant idea of automating the process with some scripting and scraping. There are tons of implementations readily available, but you realize that each time you scrape HTML, another .NET-SOA-SAAS-XML-J2EE developer is employed somewhere in the world and will somehow find a way to get on your nerves with some poorly implemented, massively bloated piece of software that you have to run through fucking Mono.

So you curse and throw up your hands, and then someone comes along and suggests HP SIM. Yes, the 1.8GB interstellar monster that somehow runs with the smallest number of wtfs on Windows 2008 with another few gigabytes of MS SQL Server on board. Oh, and then you need 800 additional megabytes for HP Insight Remote Support Advanced (RSA) which lets you do warranty lookups. Great.

In reality, all you need when looking up warranty details is a couple of lines of XML.

RSA uses HP’s Instant Support Enterprise Edition (ISEE) API, and damn is it enterprise. In short, it’s a SOAP interface that sends embedded XML documents back and forth. There’s no WSDL available, so let’s walk through the process in full, including details on the service interface.

Client Registration

A client must supply a GDID and registrationToken parameter with every warranty lookup. These parameters are obtained from the server response when the client carries out the registration process, which goes as follows:

SOAP action: http://www.hp.com/isee/webservices/RegisterClient2
HTTP URL:    https://services.isee.hp.com/ClientRegistration/ClientRegistrationService.asmx

The SOAP envelope:

File: register_soapenv.xml

<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:iseeReg="http://www.hp.com/isee/webservices/">
  <SOAP-ENV:Body>
    <iseeReg:RegisterClient2>
      <iseeReg:request>
         ...
      </iseeReg:request/>
    </iseeReg:RegisterClient2>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The ISEE registration request is then inserted as text in the <iseeReg:request> tag. It is a fairly verbose blob, and yes, it has been stripped down to the bare minimum accepted by the server.

File: register_payload.xml

<isee:ISEE-Registration schemaVersion="5.00"
    xmlns:isee="http://www.hp.com/schemas/isee/5.00/event">
  <RegistrationSource>
    <HP_OOSIdentifiers>
      <OSID>
        <Section name="SYSTEM_IDENTIFIERS">
          <Property name="TimestampGenerated"/>
        </Section>
      </OSID>
      <CSID>
        <Section name="SYSTEM_IDENTIFIERS">
          <Property name="CollectorType" value="MC3"/>
          <Property name="CollectorVersion" value="T05.80.1 build 1"/>
          <Property name="AutoDetectedSystemSerialNumber" value="10"/>
          <Property name="SystemModel" value="HP ProLiant"/>
          <Property name="TimestampGenerated"/>
        </Section>
      </CSID>
    </HP_OOSIdentifiers>
    <PRS_Address>
      <AddressType>0</AddressType>
      <Address1/>
      <Address2/>
      <Address3/>
      <Address4/>
      <City/>
      <Region/>
      <PostalCode/>
      <TimeZone/>
      <Country/>
    </PRS_Address>
  </RegistrationSource>
  <HP_ISEECustomer>
    <Business/>
    <Name/>
  </HP_ISEECustomer>
  <HP_ISEEPerson>
    <CommunicationMode>255</CommunicationMode>
    <ContactType/>
    <FirstName/>
    <LastName/>
    <Salutation/>
    <Title/>
    <EmailAddress/>
    <TelephoneNumber/>
    <PreferredLanguage/>
    <Availability/>
  </HP_ISEEPerson>
</isee:ISEE-Registration>

Note:

  • Both TimestampGenerated properties must contain a near-current timestamp on the form %Y/%m/%d %H:%M:%S %Z. Use time zone “GMT” in case of problems.
  • The AutoDetectedSystemSerialNumber property need not contain a valid serial; it’s enough with two (or more) digits.

The server will then return:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <RegisterClient2Response xmlns="http://www.hp.com/isee/webservices/">
      <RegisterClient2Result>
        <IsSuccess>true</IsSuccess>
        <Gdid>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</Gdid>
        <BackoffMultiplier>1</BackoffMultiplier>
        <RegistrationToken>XXX</RegistrationToken>
      </RegisterClient2Result>
    </RegisterClient2Response>
  </soap:Body>
</soap:Envelope>

Save the Gdid and the massively long RegistrationToken values so they can be used in upcoming requests.

Warranty Lookup

Next up is the warranty (aka entitlement) lookup itself. The GDID and registrationToken parameters are included in the SOAP/ISEE header. Again, this is the bare minimum accepted by the server, so even the empty <isee:OSID/> and <isee:CSID/> tags must be present.

SOAP action: http://www.hp.com/isee/webservices/GetOOSEntitlementList2
HTTP URL:    https://services.isee.hp.com/EntitlementCheck/EntitlementCheckService.asmx

File: warranty_soapenv.xml

<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:isee="http://www.hp.com/isee/webservices/">
  <SOAP-ENV:Header>
    <isee:IseeWebServicesHeader>
      <isee:GDID>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</isee:GDID>
      <isee:registrationToken>XXX</isee:registrationToken>
      <isee:OSID/>
      <isee:CSID/>
    </isee:IseeWebServicesHeader>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <isee:GetOOSEntitlementList2>
      <isee:request>
        ...
      </isee:request>
    </isee:GetOOSEntitlementList2>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The <isee:request> tag should then contain the following payload.

File: warranty_payload.xml

<isee:ISEE-GetOOSEntitlementInfoRequest
    xmlns:isee="http://www.hp.com/schemas/isee/5.00/entitlement"
    schemaVersion="5.00">
  <HP_ISEEEntitlementParameters>
    <CountryCode>ES</CountryCode>
    <SerialNumber>CZ10130050</SerialNumber>
    <ProductNumber>519841-425</ProductNumber>
    <EntitlementType></EntitlementType>
    <EntitlementId></EntitlementId>
    <ObligationId></ObligationId>
  </HP_ISEEEntitlementParameters>
</isee:ISEE-GetOOSEntitlementInfoRequest>

Note:

  • The empty tags must also be present.
  • The CountryCode need not match the origin country.
  • To look up multiple entries, simply add more HP_ISEEEntitlementParameters sections.

The server response SOAP envelope:

<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <GetOOSEntitlementList2Response
        xmlns="http://www.hp.com/isee/webservices/">
      <GetOOSEntitlementList2Result>
        <IsSuccess>true</IsSuccess>
        <Gdid>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</Gdid>
        <BackoffMultiplier>1</BackoffMultiplier>
        <Response>
          ...
        </Response>
      </GetOOSEntitlementList2Result>
    </GetOOSEntitlementList2Response>
  </soap:Body>
</soap:Envelope>

..and then finally, the warranty data itself. It can easily be hundreds of lines, so here’s a link to an example result: warranty-ok.xml

Each entry in the lookup is returned in its own <Data> section with a running frame count. You can also see that since the lookup specified the wrong CountryCode “US”, the response includes a warning about a mismatch with the database’s ship-to country.

Notes

There appears to be no WSDL available, so the SOAP envelope can be constructed manually or a WSDL can be reconstructed from the XML. I’m guessing that the client and server applications have been built and deployed directly from a Visual Studio project with no particular need for a WSDL.

The web interface lets you look up the serial only, but that seems to be impossible in the api. This is unfortunate for quick manual lookups, but isn’t really an issue for batch requests; the product number is readily available in any kind of iLO and also in the SMBios system SKU number.

Multiple warranty entries per request saves a lot of round-trips, but there is bound to be a maximum number of entries allowed per request. That number is not yet known.

The server returns a variety of error codes on malformed input. With the missing WSDL, error handling has to be inferred from the api by fuzzing it with invalid data. Some common error examples:

In addition to the enterprise choice of XML-in-XML, there are some odd inconsistencies in the api, such as Gdid vs GDID and RegistrationToken vs registrationToken, unused XML namespaces, inconsistent namespace local names, versioned SOAP actions (GetOOSEntitlementList2), etc. Beware when coding.

Apart from the register and entitlement lookup functions, the api supports other SOAP actions. Here’s a partial(?) list:

SOAP URLs that match some of the actions above:

Closing Words

The overall characteristics of the api makes it pretty clear that it is not designed for 3rd party use, but it certainly provides all the warranty info you need and it lets you avoid embarrassing HTML scraping. So I wish HP would publish api details and openly encourage its use, particularly for read-only authoritative data like warranty details. It doesn’t need to be the ISEE api in particular, but something well-engineered that provides the same (or better) level of detail.

As for functions other than warranty lookup, I can understand the desire to limit access to phone-home mechanisms for error reporting, hardware replacements, support cases, etc, but I would maintain that a strict api would easily limit abuse and poorly formed requests, and let competent users integrate the functionality into their own systems. One thing is for sure: Being forced to use vendor-specific, sub-par management software is definitely not the right way to go.

35 thoughts on “HP server warranty via the ISEE API

    • Those are SOAP actions, not true URLs you can fetch. See the Python script at github (link on the top) for an example of how to forge SOAP requests. Or you can use a proper SOAP library, which will make your life much easier. The challenge is to reconstruct the WSDL.

      Reply
  1. Hey there, great post, except all I’m getting from the initial call is returning just a 400 Bad Request error. The SOAP looks correct, but I’m not confident on the timestamp as I’m not familiar with Python. So, 2 questions: does this still work, or have they changed the interface? Here’s my call (I’m EST, and it’s 2:58PM here):

    string soapCall =
    @”

    0

    255

    “;

    Reply
  2. Crud, that code snipped did not work. Suffice it to say, it’s the envelope with the payload, including the 2 timestamp values and a serial#. The timestamp key is:

    Reply
    • Did you get it working? I’m not sure what would trigger the 400. Also, I can simply clone the repo and run the script as in the example, without any changes. It works every time for me. For reference, I use Python 2.7.5-6 with lxml 3.2.0-1+b1 and requests 2.0.0-1.

      There’s a potential issue with the registration token, though. I’ve ended up deleting it every time instead of re-using it. Re-using it rarely works across long time spans.

      Reply
      • I went back to screen scraping. It’s a little tricky with their latest UI, but it’s working for me. Thanks for getting back to me though. Strange that everyone but Dell makes this so difficult.

  3. Hi Foster, a few stupid questions. I’m trying to get this to work and my first issue is that using your example, I’m getting a syntax error in your code at the print etree. Line 139, not being an python coder, I’m a bit lost. I have also noticed that HP has recently update their warranty site, Do you know if this script will works?

    Reply
    • Hi, Wayne! I’m guessing you’re using Python 3, which requires parentheses around the print statement. For reference, I can make the script work by simply cloning the git repo and running the example. I currently use Python 2.7.5-6 with lxml 3.2.0-1+b1 and requests 2.0.0-1.

      Reply
    • Hi! Porting to PHP should be pretty straight forward. However, just like my prototype Python script, it is bound to be very nasty to work around the missing wsdl. Alternatively, you can simply call the Python script from PHP using some sort of command invocation call. Good luck!

      Reply
  4. does the python script still work? I am getting following errors:
    requests.exceptions.SSLError: hostname ‘services.isee.hp.com’ doesn’t match u’g1w3054g.austin.hp.com’

    Reply
    • Hi, Imran! Yes, the script still works. You’re probably using a version of the requests module that does certificate verification by default. Most likely you can add verify=False to the requests.post() call to disable cert/hostname matching. Also verify that you don’t connect through any broken proxy that mangles the request.

      Reply
  5. Using this blog, I have put together a robust PowerShell HP Warranty Lookup script. But I cannot figure out a reliable automated way to retrieve the HP Product Number. You have any ideas?

    Reply
    • Hi Brian,

      you can get the product number from the registry of each machine running the script (I guess you could also query the remote registry to store all the Product Number).

      Any chance you could share with us your HP Warranty Lookup script ?

      Reply
    • Would you mind sharing your script? I’d love to see more implementations, and it could lead to more stability and features over time. Putting it on Github would give good exposure.

      As for the product number, it is available in the SMBios system sku. Alternatively, you can decode the SMBios system UUID: It is a simple hex encoding of the product number + serial number. Beware the UUID encoding, which can be partially little endian!

      Reply
  6. I just tried example python script from top of page and it does not work.
    hpwarr.py USH14200YB,XL808AV
    File “C:\Work\hp\hpwarr.py”, line 139
    print etree.tostring(etree.fromstring(payload), pretty_print=True)

    Reply
    • Hi, Paul! Do you use Python 3? If you can, try Python 2. Alternatively, port the script to Python 3 manually or using the automated porting tools. It might be that only the print statements need parentheses.

      Reply
  7. When register new client I am getting error “Failed to get GDID!”.
    I can’t understand what is wrong.

    My config:
    python==2.6
    requests==2.1.0
    lxml==3.3.3

    Reply
    • That is not good! I have no idea what the cause is, but I’d recommend checking the XML request sent by the client. Do you run the Python script directly, or have you made any modifications?

      Reply
  8. I had to add verify=False to the requests.post() call, which is fine. But whether trying the usage example or other serial numbers from machines here I just get
    TypeError: Type ‘NoneType’ cannot be serialized.

    Reply
  9. Excellent post – this was a huge help.

    One note – It seems that HP has updated the validation check on AutoDetectedSystemSerialNumber. No idea what that is supposed to report, but my call was failing with a value of ’10’. I changed that value to ‘USM5500380′, found on the HP boards, and the registration started to work.

    The error with ’10’:


    100
    false
    true
    false
    Failed to get GDID!

    Thanks for doing all the heavy lifting!
    Chris

    Reply
  10. Hi..nice script but I get the following error:

    C:\Python27>python.exe c:\temp\hpisee.py eeeeee3e3r,519841-425,DE
    Registering new client.
    Traceback (most recent call last):
    File “c:\temp\hpisee.py”, line 266, in
    main()
    File “c:\temp\hpisee.py”, line 254, in main
    do_request(‘register’)
    File “c:\temp\hpisee.py”, line 203, in do_request
    func(payload)
    File “c:\temp\hpisee.py”, line 43, in reg_timestamp
    strftime(“%Y/%m/%d %H:%M:%S %Z”, gmtime()))
    File “lxml.etree.pyx”, line 746, in lxml.etree._Element.set (src\lxml\lxml.etr
    ee.c:42970)
    File “apihelpers.pxi”, line 547, in lxml.etree._setAttributeValue (src\lxml\lx
    ml.etree.c:19025)
    File “apihelpers.pxi”, line 1395, in lxml.etree._utf8 (src\lxml\lxml.etree.c:2
    6485)
    ValueError: All strings must be XML compatible: Unicode or ASCII, no NULL bytes
    or control characters

    can yout help me..? or is there anybody who scripted the same issue in php?

    Reply
  11. Has anyone got this working in a PowerShell script? I need to pull MSA/DAS chassis serial numbers from HP SmartArray chassis — I can parse the ACU diagnostics XML just fine to get the chassis product ID and SN, but now I need to do the warranty checking for these chassis from within my powershell script (ideally).

    If not, I guess I can play with the ocdnix python stuff, but have no experience with python.

    Thank you, ronanski

    Reply
      • Thomas,

        Thanks for your response — shortly after I found this from ocdnix – -and subsequently your excellent github HPWarranty bits, I was able to use your code (as a proof of concept) it works GREAT. Many thanks for the fine work on HPWarranty! I have a lot more to learn/explore in this area, but HPWarranty has helped me “sell” my management on some important points.

        I”m curious as to what you are “refining” – compared to other code/functions/modules I have found prior to finding your code (which seems to work “out of the box” at least when I feed it data I believe should result in a successful response) — most everything else seems to have many rough edges; but again I am only doing some basic testing/demos.

        I need to play around with Github as well….

        Actually I am also interested in automating HP ProLiant (DLXXX) server monitoring and management, leveraging / ISEE / IRS/IRSA (managing iLO advanced licenses, semi-automating generation of HP support tickets to receive parts for supported servers — WITHOUT having to commit to expensive HP software like such as Insight Control or the upcoming OneView (our organization currently manages most everything with System Center, including imaging OS with SCCM, OSD). My company has purchased Insight Control however most of what it CAN do we either do not need, or we have little resources to allocate engineers to manage.

        The idea of using PS (is now or becoming a standard Windows scripting shell/language) to manage Windows servers leveraging whatever automation APIs HP iLO, ISEE and HP agents we can access — is much easier for me to justify than procuring expensive management frameworks designed to do everything under the sun and more (and requiring multiple application engineers to manage).

        But then I like to tinker .. just me!

        Thank you
        Ronanski

  12. Hi,

    Thank you for the great post, and I have written a Java program that does the same thing based on your code. Thanks.

    I was stuck for a while, keep getting 400 bad request errors, and I eventually went ahead and reverse engineered the entire soap message sent by your program, captured it, output it to file and found the difference and fixed my code.

    The xml message being sent by your program uses “” symbols at the envelop for the tags, and in the python generated payload part, it uses the “<” and “>”. Which should be the same thing and shouldn’t affect the decoding of the xml on HP side. But it does, it was the only difference between a successful request and a 400 bad request.

    I plan to write a post on this, about how that is the issue. But I would like to get your insight on this, what might be the cause? Is this really the issue? Did you realize this when you develop the tool?

    Thank you so much again, Looking forward to your reply.

    Kaiwei

    Reply
    • correction, the text editor automatically parsed my input. I meant that in the envelop, it uses the actual greater and less than signs, and in the pay load, it uses the “amp lt k;”. the four character representation of the tags instead of the symbol.

      Reply

Leave a reply to Wayne Carvey Cancel reply