使用PowerShell SOAP进行HP保修查询

时间:2013-10-21 19:51:40

标签: powershell soap

到目前为止,惠普保修信息的网络抓取工作正常,但是在最近几周他们已经改变了网页,看起来他们现在正在新网页上使用POST而不是GET,这意味着我不能实际上只是将信息传递给URL。

我确实在本页的解决方案中找到了一些希望:
http://ocdnix.wordpress.com/2013/03/14/hp-server-warranty-via-the-isee-api/
但我不明白示例脚本,因为我之前没有使用过Python。

我还发现这个网页向我展示了戴尔保修的一个很好的例子,但惠普没有我可以使用的WSDL。 (我会发布链接,但没有足够的代表)

使用这些功能我可以形成请求:
http://www.iislogs.com/steveschofield/execute-a-soap-request-from-powershell

我认为一切都会按预期工作,但我很难形成注册客户端的请求,我不断收到500个错误,这意味着他们的服务器坏了或我的请求导致内部错误。

我第一次完全不知所措。

是否有人在PowerShell中使用此功能或遇到类似问题?

更新了22-10-13

我现在有了信封,我设法让Python脚本运行但由于我的代理失败了,所以提取生成的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><isee:ISEE-Registration xmlns:isee="http://www.hp.com/schemas/isee/5.00/event" schemaVersion="5.00">
<RegistrationSource>
    <HP_OOSIdentifiers>
    <OSID>
        <Section name="SYSTEM_IDENTIFIERS">
        <Property name="TimestampGenerated" value="2013/10/22 09:40:35 GMT Standard Time"/>
        </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" value="2013/10/22 09:40:35 GMT Standard Time"/>
        </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></iseeReg:request>
    </iseeReg:RegisterClient2>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

然后我构建了一个执行如下操作的Powershell脚本:

function Execute-SOAPRequest {
Param (
[Xml]$SOAPRequest,
[String]$URL,
[switch]$UseProxy
)

write-host "Sending SOAP Request To Server: $URL" 
$soapWebRequest = [System.Net.WebRequest]::Create($URL) 
$soapWebRequest.Headers.Add("SOAPAction",'"http://www.hp.com/isee/webservices/RegisterClient2"') 

$soapWebRequest.ContentType = 'text/xml; charset=utf-8'
$soapWebRequest.Accept = "text/xml" 
$soapWebRequest.Method = "POST" 
$soapWebRequest.UserAgent = 'RemoteSupport/A.05.05 - gSOAP/2.7'

#$soapWebRequest.ServicePoint.Expect100Continue = $False
#$soapWebRequest.ServicePoint.MaxIdleTime = 2000
$soapWebRequest.ProtocolVersion = [system.net.httpversion]::version10

if($UseProxy){
    $soapWebRequest.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
}


write-host "Initiating Send." 
$requestStream = $soapWebRequest.GetRequestStream() 
$SOAPRequest.Save($requestStream) 
$requestStream.Close() 

write-host "Send Complete, Waiting For Response." 
$resp = $soapWebRequest.GetResponse() 
$responseStream = $resp.GetResponseStream() 
$soapReader = [System.IO.StreamReader]($responseStream) 
$ReturnXml = [Xml]$soapReader.ReadToEnd() 
$responseStream.Close() 

write-host "Response Received." 

return $ReturnXml 
} 

$SOAPRequest = [Xml](Get-Content 'C:\Temp\SoapEnv.xml')
$URL = 'https://services.isee.hp.com/ClientRegistration/ClientRegistrationService.asmx'

Execute-SOAPRequest $SOAPRequest $URL -UseProxy

但是现在我得到了额外的错误,而不是500我越来越接近?错误详情如下:

Exception calling "GetRequestStream" with "0" argument(s): "The server committed a protocol violation. Section=ResponseStatusLine"
At C:\Temp\HP Register Client.ps1:29 char:54
+     $requestStream = $soapWebRequest.GetRequestStream <<<< () 
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

6 个答案:

答案 0 :(得分:3)

试试这个。 。对我来说很合适:注意:只需要转义请求标记。

$SOAPRequest= [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>&lt;isee:ISEE-Registration xmlns:isee="http://www.hp.com/schemas/isee/5.00/event" schemaVersion="5.00"&gt;
&lt;RegistrationSource&gt;
    &lt;HP_OOSIdentifiers&gt;
    &lt;OSID&gt;
        &lt;Section name="SYSTEM_IDENTIFIERS"&g`enter code here`t;
        &lt;Property name="TimestampGenerated" value="2013/12/06 14:04:24 EST"/&gt;
        &lt;/Section&gt;
    &lt;/OSID&gt;
    &lt;CSID&gt;
        &lt;Section name="SYSTEM_IDENTIFIERS"&gt;
        &lt;Property name="CollectorType" value="MC3"/&gt;
        &lt;Property name="CollectorVersion" value="T05.80.1 build 1"/&gt;
        &lt;Property name="AutoDetectedSystemSerialNumber" value="10"/&gt;
        &lt;Property name="SystemModel" value="HP ProLiant"/&gt;
        &lt;Property name="TimestampGenerated" value="2013/12/06 14:04:24 EST"/&gt;
        &lt;/Section&gt;
    &lt;/CSID&gt;
    &lt;/HP_OOSIdentifiers&gt;
    &lt;PRS_Address&gt;
    &lt;AddressType&gt;0&lt;/AddressType&gt;
    &lt;Address1/&gt;
    &lt;Address2/&gt;
    &lt;Address3/&gt;
    &lt;Address4/&gt;
    &lt;City/&gt;
    &lt;Region/&gt;
    &lt;PostalCode/&gt;
    &lt;TimeZone/&gt;
    &lt;Country/&gt;
    &lt;/PRS_Address&gt;
&lt;/RegistrationSource&gt;
&lt;HP_ISEECustomer&gt;
    &lt;Business/&gt;
    &lt;Name/&gt;
&lt;/HP_ISEECustomer&gt;
&lt;HP_ISEEPerson&gt;
    &lt;CommunicationMode&gt;255&lt;/CommunicationMode&gt;
    &lt;ContactType/&gt;
    &lt;FirstName/&gt;
    &lt;LastName/&gt;
    &lt;Salutation/&gt;
    &lt;Title/&gt;
    &lt;EmailAddress/&gt;
    &lt;TelephoneNumber/&gt;
    &lt;PreferredLanguage/&gt;
    &lt;Availability/&gt;
&lt;/HP_ISEEPerson&gt;
&lt;/isee:ISEE-Registration&gt;</iseeReg:request>
    </iseeReg:RegisterClient2>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
"@

您必须为保修xml做同样的事情,然后重新运行soap web请求。

$hpgdid = $ReturnXml.envelope.body.RegisterClient2Response.RegisterClient2Result.Gdid
$hptoken = $ReturnXml.envelope.body.RegisterClient2Response.RegisterClient2Result.registrationtoken


$warrantyxml = [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>$hpgdid</isee:GDID>
      <isee:registrationToken>$hptoken</isee:registrationToken>
      <isee:OSID/>
      <isee:CSID/>
    </isee:IseeWebServicesHeader>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <isee:GetOOSEntitlementList2>
      <isee:request>
        &lt;isee:ISEE-GetOOSEntitlementInfoRequest
    xmlns:isee="http://www.hp.com/schemas/isee/5.00/entitlement"
    schemaVersion="5.00"&gt;
  &lt;HP_ISEEEntitlementParameters&gt;
    &lt;CountryCode&gt;ES&lt;/CountryCode&gt;
    &lt;SerialNumber&gt;CZ10130050&lt;/SerialNumber&gt;
    &lt;ProductNumber&gt;519841-425&lt;/ProductNumber&gt;
    &lt;EntitlementType&gt;&lt;/EntitlementType&gt;
    &lt;EntitlementId&gt;&lt;/EntitlementId&gt;
    &lt;ObligationId&gt;&lt;/ObligationId&gt;
  &lt;/HP_ISEEEntitlementParameters&gt;
&lt;/isee:ISEE-GetOOSEntitlementInfoRequest&gt;
      </isee:request>
    </isee:GetOOSEntitlementList2>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
"@

$xmlstring = [string]$ReturnXml.Envelope.Body.GetOOSEntitlementList2Response.GetOOSEntitlementList2Result.Response

$warranty_info = [xml]@"
$xmlstring
"@

 $warranty_info."ISEE-GetOOSEntitlementInfoResponse"

答案 1 :(得分:3)

我已将其构建到PowerShell模块中,我将SOAP请求移动到单独的XML文件中,并使用CDATA使它们更具可读性。它对我来说非常好用。它可以在GitHub上找到:

https://github.com/dotps1/HPWarranty

感谢此页面上的所有信息,真的很有帮助!

答案 2 :(得分:0)

您需要像下面那样转义正在传输的XML。还要确保TimestampGenerated的格式也正确。

<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>&lt;isee:ISEE-Registration xmlns:isee="http://www.hp.com/schemas/isee/5.00/event" schemaVersion="5.00"&gt;
&lt;RegistrationSource&gt;
    &lt;HP_OOSIdentifiers&gt;
    &lt;OSID&gt;
        &lt;Section name="SYSTEM_IDENTIFIERS"&gt;
        &lt;Property name="TimestampGenerated" value="2013/12/05 19:24:58 GMT"/&gt;
        &lt;/Section&gt;
    &lt;/OSID&gt;
    &lt;CSID&gt;
        &lt;Section name="SYSTEM_IDENTIFIERS"&gt;
        &lt;Property name="CollectorType" value="MC3"/&gt;
        &lt;Property name="CollectorVersion" value="T05.80.1 build 1"/&gt;
        &lt;Property name="AutoDetectedSystemSerialNumber" value="10"/&gt;
        &lt;Property name="SystemModel" value="HP ProLiant"/&gt;
        &lt;Property name="TimestampGenerated" value="2013/12/05 19:24:58 GMT"/&gt;
        &lt;/Section&gt;
    &lt;/CSID&gt;
    &lt;/HP_OOSIdentifiers&gt;
    &lt;PRS_Address&gt;
    &lt;AddressType&gt;0&lt;/AddressType&gt;
    &lt;Address1/&gt;
    &lt;Address2/&gt;
    &lt;Address3/&gt;
    &lt;Address4/&gt;
    &lt;City/&gt;
    &lt;Region/&gt;
    &lt;PostalCode/&gt;
    &lt;TimeZone/&gt;
    &lt;Country/&gt;
    &lt;/PRS_Address&gt;
&lt;/RegistrationSource&gt;
&lt;HP_ISEECustomer&gt;
    &lt;Business/&gt;
    &lt;Name/&gt;
&lt;/HP_ISEECustomer&gt;
&lt;HP_ISEEPerson&gt;
    &lt;CommunicationMode&gt;255&lt;/CommunicationMode&gt;
    &lt;ContactType/&gt;
    &lt;FirstName/&gt;
    &lt;LastName/&gt;
    &lt;Salutation/&gt;
    &lt;Title/&gt;
    &lt;EmailAddress/&gt;
    &lt;TelephoneNumber/&gt;
    &lt;PreferredLanguage/&gt;
    &lt;Availability/&gt;
&lt;/HP_ISEEPerson&gt;
&lt;/isee:ISEE-Registration&gt;</iseeReg:request>
    </iseeReg:RegisterClient2>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

另一个选择而不是自己转义XML的选择是将它放在CDATA中,以便它不被解析:http://www.w3schools.com/xml/xml_cdata.asp

答案 3 :(得分:0)

结合我在网络上找到的所有信息,我创建了以下基于Serial Number完成所有功能的功能。特别感谢 dotps1 的辛勤工作。

对于HP:

Function Get-HPAssetInformationHC {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory,ValueFromPipeline)]
        [String]$SerialNumber
    )

    Begin {
        Function Invoke-HPIncSOAPRequest {
            Param (
                [Parameter(Mandatory)]
                [Xml]$SOAPRequest,
                [String]$Url = 'https://api-uns-sgw.external.hp.com/gw/hpit/egit/obligation.sa/1.1'
            )

            $soapWebRequest = [System.Net.WebRequest]::Create($URL) 
            $soapWebRequest.Headers.Add('X-HP-SBS-ApplicationId','hpi-obligation-hpsa')
            $soapWebRequest.Headers.Add('X-HP-SBS-ApplicationKey','ft2VGa2hx9j$')
            $soapWebRequest.ContentType = 'text/xml; charset=utf-8'
            $soapWebRequest.Accept = 'text/xml'
            $soapWebRequest.Method = 'POST'

            try {
                $SOAPRequest.Save(($requestStream = $soapWebRequest.GetRequestStream()))
                $requestStream.Close() 
                $responseStream = ($soapWebRequest.GetResponse()).GetResponseStream()
                [XML]([System.IO.StreamReader]($responseStream)).ReadToEnd()
                $responseStream.Close() 
            }
            catch {
                throw $_
            }
        }
    }

    Process {
        foreach ($S in $SerialNumber) {
            $request = @"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:int="http://interfaces.obligation.sbs.it.hp.com/">
  <soapenv:Header />
  <soapenv:Body>
    <int:retrieveServiceObligationResponsesByServiceObligationRequests>
      <context>
        <appContextName>HPSF</appContextName>
        <userLocale>en-US</userLocale>
      </context>
      <obligationRequests>
        <lnkServiceObligationDepthFilter>
          <includeProductObjectOfServiceInstance>true</includeProductObjectOfServiceInstance>
          <includeServiceObligation>true</includeServiceObligation>
          <includeServiceObligationHeaderOffer>true</includeServiceObligationHeaderOffer>
          <includeServiceObligationMessage>true</includeServiceObligationMessage>
          <maxNumberOfProductObjectOfServiceInstance>100</maxNumberOfProductObjectOfServiceInstance>
        </lnkServiceObligationDepthFilter>
        <lnkServiceObligationEnrichment>
          <iso2CountryCode>US</iso2CountryCode>
        </lnkServiceObligationEnrichment>
        <lnkServiceObligationProductObjectOfServiceIdentifier>
          <hpSerialNumber>$S</hpSerialNumber>
        </lnkServiceObligationProductObjectOfServiceIdentifier>
      </obligationRequests>
    </int:retrieveServiceObligationResponsesByServiceObligationRequests>
  </soapenv:Body>
</soapenv:Envelope>
"@

            Try {
                [XML]$entitlement = Invoke-HPIncSoapRequest -SOAPRequest $request -ErrorAction Stop
            }
            Catch {
                $P = $_
                $Global:Error.RemoveAt(0)
                throw "Failed to invoke SOAP request: $P"
            }

            Try {
                if ($entitlement) {
                    $HPAsset = $entitlement.Envelope.Body.retrieveServiceObligationResponsesByServiceObligationRequestsResponse.return

                    [PSCustomObject][Ordered]@{
                        SerialNumber           = $S
                        ProductNumber          = $HPAsset.lnkProductObjectOfServiceInstance.ProductNumber
                        SalesOrderNumber       = $HPAsset.lnkServiceObligations.salesOrderNumber | where {$_}
                        ProductDescription     = $HPAsset.lnkProductObjectOfServiceInstance.productDescription
                        ProductLineDescription = $HPAsset.lnkProductObjectOfServiceInstance.productLineDescription
                        ActiveEntitlement      = $HPAsset.lnkServiceObligations.serviceObligationActiveIndicator
                        OfferDescription       = $HPAsset.lnkServiceObligationHeaderOffer | where serviceQuantity -GE 1 | Select-Object -ExpandProperty offerDescription
                        StartDate              = $HPAsset.lnkServiceObligations.serviceObligationStartDate | ForEach-Object {[DateTime]$_}
                        EndDate                = $HPAsset.lnkServiceObligations.serviceObligationEndDate | ForEach-Object {[DateTime]$_}
                    }

                    Write-Verbose "HP asset '$($HPAsset.lnkProductObjectOfServiceInstance.productDescription)' with serial number '$S'"
                }
                else {
                    Write-Warning "No HP asset information found for serial number '$S'"
                    continue
                }
            }
            Catch {
                $P = $_
                $Global:Error.RemoveAt(0)
                throw "Failed to invoke SOAP request: $P"
            }
        }
    }
}

对于戴尔:

Function Get-DellAssetInformationHC {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [String[]]$SerialNumber
    )

    Begin {
        # Possible API keys
        # 1adecee8a60444738f280aad1cd87d0e
        # d676cf6e1e0ceb8fd14e8cb69acd812d
        # 1adecee8a60444738f280aad1cd87d0e
        # 849e027f476027a394edd656eaef4842

        $APIKey = '849e027f476027a394edd656eaef4842'
    }

    Process {
        foreach ($S in $SerialNumber) {
            Try {
                $DellURL = "https://api.dell.com/support/v2/assetinfo/warranty/tags.xml?svctags=$S&apikey=$APIKey"

                $XML = New-Object System.Xml.XmlDocument
                $XML.Load($DellURL)
                $DellAsset = $XML.GetAssetWarrantyResponse.GetAssetWarrantyResult.Response.DellAsset

                if ($DellAsset) {
                    [PSCustomObject][Ordered]@{
                        SerialNumber            = $S
                        CustomerNumber          = $DellAsset.CustomerNumber
                        OrderNumber             = $DellAsset.OrderNumber
                        MachineDescription      = $DellAsset.MachineDescription
                        ShipDate                = $DellAsset.ShipDate
                        ServiceLevelDescription = $DellAsset.Warranties.Warranty.ServiceLevelDescription
                        StartDate               = $DellAsset.Warranties.Warranty.StartDate | ForEach-Object {[DateTime]$_}
                        EndDate                 = $DellAsset.Warranties.Warranty.EndDate | ForEach-Object {[DateTime]$_}
                    }

                    Write-Verbose "Dell asset '$($DellAsset.MachineDescription)' with serial number '$S'"
                }
                else {
                    Write-Warning "No Dell asset information found for serial number '$S'"
                }
            }
            Catch {
                $P = $_
                $Global:Error.RemoveAt(0)
                throw "Failed retrieving Dell asset information for serial number '$S': $P"
            }
        }
    }
}

答案 4 :(得分:0)

我们无法针对公开网址进行http POST的任何原因:http://h20564.www2.hpe.com/hpsc/wc/public/find

我们可以像这样用curl做一个http POST(例如把它放在一个脚本中):

/ usr / bin / curl&#39; http://h20564.www2.hpe.com/hpsc/wc/public/find&#39; \ - 压缩\ -H&#39;接受:text / html,application / xhtml + xml,application / xml; q = 0.9, / ; q = 0.8&#39; \ -H&#39;接受编码:gzip,deflate&#39; \ -H&#39;接受语言:en-US,en; q = 0.5&#39; \ -H&#39;连接:保持活力&#39; \ -H&#39;主持人:h20564 .www2.hpe.com&#39; \ -H&#39; Referer :(缺少https:这里)h20564.www2.hpe.com/hpsc/wc/public/home' \ -H&#39;升级 - 不安全请求:1&#39; \ -H&#39; User-Agent:Mozilla / 5.0(X11; Ubuntu; Linux x86_64; rv:49.0)Gecko / 20100101 Firefox / 49.0&#39; \ -H&#39;内容类型:application / x-www-form-urlencoded&#39; \ --data-binary&#39; @ / tmp / data&#39; | grep hpui-standard-table

它需要的唯一额外的东西-H&#39; Cookie:&#39;头。我可以从网页查找中复制相同的cookie,但我不确定可以使用多长时间。

数据文件位于/ tmp / data中,格式如下:

  

rows [0] .item.countryCode = US rows [0] .item.serialNumber = XXXXXXXXX   rows [1] .item.countryCode = US rows [1] .item.serialNumber = YYYYYYYYY   rows [2] .item.countryCode = US rows [2] .item.serialNumber =   rows [3] .item.countryCode = US rows [3] .item.serialNumber =   rows [4] .item.countryCode = US rows [4] .item.serialNumber =   rows [5] .item.countryCode = US rows [5] .item.serialNumber =   rows [6] .item.countryCode = US rows [6] .item.serialNumber =   rows [7] .item.countryCode = US rows [7] .item.serialNumber =   rows [8] .item.countryCode = US rows [8] .item.serialNumber =   rows [9] .item.countryCode = US rows [9] .item.serialNumber =   提交按钮=提交

答案 5 :(得分:0)

现在惠普开发了api以获得机器产品保修。它正处于测试阶段,但我们可以尝试一下。希望尽快将其转移到生产中。您必须在此处查看文档并填写所需的详细信息。您将拥有自己的api密钥。

https://developers.hp.com/css-enroll

谢谢, Prabha。