HP Warranty Lookup using PowerShell SOAP - powershell

Up to recently the web scraping of HP warranty information worked fine, however in the last couple of weeks they have changed the web page and it seems they are using POST rather than GET now on the new page, meaning I can't really just pass the information to the URL.
I did find some hope in a solution on this page:
http://ocdnix.wordpress.com/2013/03/14/hp-server-warranty-via-the-isee-api/
But I don't understand the example script as I have not worked with Python before.
I also found this web page that shows me a good example for Dell warranty, But HP don't have a WSDL that I could work with. (I would post the link but don't have enough rep)
Using these functions I can form the request:
http://www.iislogs.com/steveschofield/execute-a-soap-request-from-powershell
I think everything will work as expected but I am struggling to form the request to register the client, I keep getting 500 errors which either means their server is broken or my request is causing an internal error.
I am for the first time completely at a loss with this.
Anybody got this to work in PowerShell or having similar issues?
Updated 22-10-13
I now have the envelope, I managed to get the Python script to run but that failed because of my proxy, so extracted the generated XML which is what I wanted as I wasn't sure how it should be formed, this looks like:
<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>
I then built a Powershell script that executes like this:
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
But now I am getting additional errors rather than the 500 I was getting so getting closer?? Error details are:
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

try this. . works for me just fine: Note: Only the request tag needs to be escaped.
$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><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"&g`enter code here`t;
<Property name="TimestampGenerated" value="2013/12/06 14:04:24 EST"/>
</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/12/06 14:04:24 EST"/>
</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>
"#
You'll have to do the same thing for the warranty xml like so then just re-run the soap web request.
$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>
<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>
</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"

I have built this into a PowerShell Module, I moved the SOAP Requests to separate XML files, and used CDATA to make them much more readable. It works pretty well for me. it can be found on GitHub:
https://github.com/dotps1/HPWarranty
Thanks for all of the info on this page, really helped!

You need to escape the XML being transferred like below. Also make sure that the TimestampGenerated is formatted properly as well.
<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/12/05 19:24:58 GMT"/>
</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/12/05 19:24:58 GMT"/>
</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>
Another option instead of escaping the XML yourself would be to place it within a CDATA so that it isn't parsed: http://www.w3schools.com/xml/xml_cdata.asp

Combining all the information I found all over the web, I've created the following function that does it all based on the Serial Number. Special thanks to dotps1 for his hard work.
For 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"
}
}
}
}
For Dell:
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"
}
}
}
}

Any reason why we cannot just do a http POST against the publicly available URL: http://h20564.www2.hpe.com/hpsc/wc/public/find
We can do an http POST with curl like this (put this in a script, for example):
/usr/bin/curl 'http://h20564.www2.hpe.com/hpsc/wc/public/find' \
--compressed \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'Connection: keep-alive' \
-H 'Host: h20564.www2.hpe.com' \
-H 'Referer: (missing https: here) h20564.www2.hpe.com/hpsc/wc/public/home' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-binary '#/tmp/data' | grep hpui-standard-table
The only extra thing it needs the -H 'Cookie: ' header. I can copy the same cookie from a web lookup, but I am not sure how long that can be used.
The data file is in /tmp/data, formatted like this:
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=
submitButton=Submit

Now HP has developed api for getting machines product warranty. It is in testing phase however we can try it. Hope it will be moved to production As Soon As Possible. You have to go through the document here and fill the details they required. You will have your own api key to work with.
https://developers.hp.com/css-enroll
Thanks,
Prabha.

Related

Cannot make Powershell work for windows notification

I want to test notification in Powershell
I tried solution found on SO with https://gist.github.com/altrive/72594b8427b2fff16431
no error but no notification (I checked Background apps is on).
Then I tried this snippet (taken here https://michael-casey.com/2019/05/12/schedule-windows-notifications-with-powershell/) but I get error Exception calling "LoadXml" with "1" argument(s): "Exception from HRESULT: 0xC00CE558" and can't see how to fix it :
function test {
$app = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe'
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$Template = [Windows.UI.Notifications.ToastTemplateType]::ToastImageAndText01
$ToastTemplate = ([Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent($Template).GetXml())
$ToastTemplate = #"
<toast launch="app-defined-string">
<visual>
<binding template="ToastGeneric">
<text>Prevent Eye Strain</text>
<text>Take a 20 second break</text>
</binding>
</visual>
</toast>
"#
$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
$ToastXml.LoadXml($ToastTemplate.OuterXml)
$notify = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($app)
$notify.Show($ToastXml)
#source: https://gist.github.com/Windos/9aa6a684ac583e0d38a8fa68196bc2dc
}

Not able to Get the Last node of an xml node properly

I am having 2 diffrent xml file with. Currently im trying to get the Last xml node. In the 1st ouput im getting because empty or Null value since i have a commented line. Please help how to handle in this case.
#Below line Run firstfile.xml
$xmlfile = 'C:\Programs\MyTasks\TCPROD-29658\Test_1309\D_SimulationTest\firstfile.xml'
#Below line to Run secondfile.xml
#$xmlfile = 'C:\Programs\MyTasks\TCPROD-29658\Test_1309\D_SimulationTest\secondfile.xml'
$xmllastsitenode = [xml]::new()
$xmllastsitenode.Load($xmlFile)
$lastsite_id = $xmllastsitenode.fccconfig.fccdefaults.LastChild.id
write-host 'Print1'
write-host $lastsite_id
if (!$lastsite_id) { Write-Host "variable is null" }
if ($lastsite_id) { Write-Host "variable is NOT null" }
write-host 'Print2'
Below is the xml files im trying to run
1st XML file
<?xml version="1.0" encoding="UTF-8"?>
<fccconfig version="1.3.2">
<fccdefaults>
<property name="CacheLocation" value="C:/Users/Public/" overridable="true"/>
<site id="-1940805554" overridable="true">
<parentfsc address="http://abcdefgh:1234/" priority="0" />
</site>
<!--__ANT_MARK__-->
</fccdefaults>
<!-- default parentfsc - this is a marker that will be overwritten by the installer -->
<parentfsc address="xyzlmnopq:10010" priority="0" transport="lan"/>
</fccconfig>
Output:-
Print1
variable is null
Print2
2nd XML file
<?xml version="1.0" encoding="UTF-8"?>
<fccconfig version="1.3.2">
<fccdefaults>
<property name="CacheLocation" value="C:/Users/Public/" overridable="true"/>
<site id="-1940805554" overridable="true">
<parentfsc address="http://abcdefgh:1234/" priority="0" />
</site>
</fccdefaults>
<!-- default parentfsc - this is a marker that will be overwritten by the installer -->
<parentfsc address="xyzlmnopq:10010" priority="0" transport="lan"/>
</fccconfig>
Output:-
Print1
-1940805554
variable is NOT null
Print2
Latest Code which have tried meantime
#Below line Run firstfile.xml
$xmlfile = 'C:\Programs\MyTasks\TCPROD-29658\Test_1309\D_SimulationTest\firstfile.xml'
#Below line to Run secondfile.xml
#$xmlfile = 'C:\Programs\MyTasks\TCPROD-29658\Test_1309\D_SimulationTest\secondfile.xml'
$xmllastsitenode = [xml]::new()
$xmllastsitenode.Load($xmlFile)
$lastsite_id = $xmllastsitenode.fccconfig.fccdefaults.LastChild.id
write-host 'Print1'
write-host $lastsite_id
if (!$lastsite_id)
{
Write-Host "variable is null"
# New logic to handle firt xml file cases
#$somesitetag ---> Having some xml tag content here
$newSiteNode = $xmlcontent.ImportNode($somesitetag, $true)
$antmarkline = (Get-Content $xmlfile) | select-string -Pattern $antmark
$xmlcontent.fccconfig.fccdefaults.InsertAfter($newSiteNode,$antmarkline)
}
if ($lastsite_id)
{
Write-Host "variable is NOT null"
#Insterting some new nodes
#This Working as second file conetent works here
}
write-host 'Print2'
You need to ignore the comments. Check the output of this for the first XML file.
$settings = [System.Xml.XmlReaderSettings]::new()
$settings.IgnoreComments = $true
$xmlreader = [System.Xml.XmlReader]::Create('./Desktop/Test.xml', $settings)
$xmldoc = [System.Xml.XmlDocument]::new()
$xmldoc.Load($xmlreader)
$xmldoc.fccconfig.fccdefaults.LastChild

Authentication Issue with eBatNS Trading API trying to get SessionID

I'm trying to get a session ID using the eBatNS SOAP API.
The function which makes the call is pretty simple, but always returns an Authentication error. You can see the function below
public function get_ebay_session()
{
error_reporting(0);
$ruName = "Forward_Thinker-ForwardT-57fe-4-rybapdi";
$sessionID = "";
//Connect to eBay and get a list of all products
require_once 'eBay/EbatNs/EbatNs_ServiceProxy.php';
require_once 'eBay/EbatNs/GetSessionIDRequestType.php';
require_once 'eBay/EbatNs/EbatNs_Logger.php';
//Get a SessionID
$session = new EbatNs_Session('eBay/config/ebay.config.php');
print_r($session);
echo "<hr>";
$cs = new EbatNs_ServiceProxy($session);
$cs->attachLogger(new EbatNs_Logger(false, 'stdout', true, false));
print_r($cs);
echo "<hr>";
$req = new GetSessionIDRequestType();
$req->setRuName($ruName);
print_r($req);
echo "<hr>";
$result = $cs->GetSessionID($req);
$sessionID = $result->SessionID;
print_r($result);
echo "<hr>";
session_start();
$_SESSION['eBaySessionID'] = $sessionID;
$return = $ruName."\n".$sessionID;
$this->set(compact('return'));
}
As you can see I have attached a logger. The logger shows that this is the request being made.
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns="urn:ebay:apis:eBLBaseComponents" ><soap:Header><RequesterCredentials><eBayAuthToken>AgAAAA**AQAAAA**aAAAAA**wS7oUQ**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6wHloSkD5aGog+dj6x9nY+seQ**It4BAA**AAMAAA**CB7yrHTyG3kQbA6KOwf0ZO2MqyPs/Dfn5u5r8ZDVGeWNvB</eBayAuthToken><Credentials><AppId>ForwardT-57fe-41ea-b90e-52fd0b541b88</AppId><DevId>5eefba38-e226-4876-9ada-d8743f571aeb</DevId><AuthCert>b57984cb-ba9c-430c-a8fc-c08f9ac46e75</AuthCert></Credentials></RequesterCredentials></soap:Header><soap:Body><GetSessionIDRequest><Version><![CDATA[815]]></Version><RuName><![CDATA[Forward_Thinker-ForwardT-57fe-4-rybapdi]]></RuName></GetSessionIDRequest></soap:Body></soap:Envelope>
And that this is the response being returned:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode xmlns:ns1="http://xml.apache.org/axis/">ns1:FailedCheck</faultcode>
<faultstring>Authorisation token is invalid.</faultstring>
<faultactor>http://www.ebay.com/ws/websvc/eBayAPI</faultactor>
<detail>
<FaultDetail>
<ErrorCode>931</ErrorCode>
<Severity>Error</Severity>
<DetailedMessage>Validation of the authentication token in API request failed.</DetailedMessage>
</FaultDetail>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
My ebay.config.php file has all the correct keys and, as far as I can tell, all of the correct information. Does anyone have any tips for resolution?
Danny
This issue was caused by the eBatNS API sending a token from a previous request in the request to get a new token. This isn't supported by ebay.
This is resolved by setting the token mode on the session to 0 or false.
$session->setTokenMode(0)

Best way to handle large amount of nested data in powershell?

I'm trying to automate the logfiles verification of our daily batch.
I want to check around 20 servers that may have up to 30 batch, each batch can generate one or more logfiles and I want to validate them using several criteria.
So this ends up with a quite huge amount of data.
My first though was to use nested arrays and hashtables then create psobject like this :
$servers=#(
#{
"name"="server1";
"credential"="domain\user";
"batch"=#(
#{"batchName"="test";"path"="e:\cit\sauvegarde\batch\recup.cmd";"comment"="batch de test";"schedule"="lundi,mardi ";
"validations"=#(
#{"name"="log exist";"path"="\\smacweb\e$\cit\test.log";"filter"=#("NotNull";"NotOlderThan,2") };
#{"name"="no erros";"path"="\\smacweb\CIT\sauvegarde\logs\*.log";"filter"=#("NotContains,'error'") };
)};
#{"batchName"="mysql";"comment"="dump des bases mysql";"schedule"="lundi,mardi,vendredi";
"validations"=#(
#{"name"="log exist";"path"="\\smacweb\e$\mysqldump\dump.zip";"filter"=#("NotNull";"NotOlderThan,2") };
#{"name"="zipOK";"path"="\\smacweb\e$\mysqldump\dump.zip";"filter"=#("Test-Zip") };
)};
)
};
# #{
# "name"="server2";
# "credential"="domain\user2";
# "batch"=#(
# #{"batchName"=.....};
# )};
)
$srv=#()
$servers | % {
$srv+= New-Object -TypeName psobject -Property $_;
}
This is a small example but I guess it will quickly become hardly readable.
So what would be a better way to do this? Use xml (not familiar to me), use external database, other method?
Caution: I'm a noob when it comes to xml, but I gave it a try for fun. This is just an example of how you could navigate through the xml-file. :)
XML file (test.xml):
<?xml version="1.0" encoding="utf-8"?>
<servers>
<server>
<servername>server1</servername>
<credential>domain\user</credential>
<batches>
<batch>
<batchname>test</batchname>
<batchpath>e:\cit\sauvegarde\batch\recup.cmd</batchpath>
<comment>batch de test</comment>
<schedule>
<day>lundi</day>
<day>mardi</day>
</schedule>
<validations>
<validation>
<name>log exist</name>
<path>\\smacweb\e$\cit\test.log</path>
<filters>
<filter>NotNull</filter>
<filter>NotOlderThan,2</filter>
</filters>
</validation>
<validation>
<name>no erros</name>
<path>\\smacweb\CIT\sauvegarde\logs\*.log</path>
<filters>
<filter>NotContains,'error'</filter>
</filters>
</validation>
</validations>
</batch>
<batch>
<batchname>mysql</batchname>
<comment>dump des bases mysql</comment>
<schedule>
<day>lundi</day>
<day>mardi</day>
<day>vendredi</day>
</schedule>
<validations>
<validation>
<name>log exist</name>
<path>\\smacweb\e$\mysqldump\dump.zip</path>
<filters>
<filter>NotNull</filter>
<filter>NotOlderThan,2</filter>
</filters>
</validation>
<validation>
<name>zipOK</name>
<path>\\smacweb\e$\mysqldump\dump.zip</path>
<filters>
<filter>Test-Zip</filter>
</filters>
</validation>
</validations>
</batch>
</batches>
</server>
</servers>
Powershell-script to loop through servers and batches:
function test {
$xml = [xml](Get-Content C:\Users\Frode\Desktop\test.xml)
$servers = $xml.SelectNodes("/servers/server")
foreach ($server in $servers) {
$batches = $server.SelectNodes("batches/batch")
Write-Host "Server: $($server.servername)"
foreach ($batch in $batches) {
Write-Host "Checking batch: $($batch.batchname)"
}
}
}
Output:
PS-ADMIN C:\Windows\system32> test
Server: server1
Checking batch: test
Checking batch: mysql

How to send raw xml to SOAP server using Zend_Soap_Client?

I'm traying to send a raw request to a SOAP server. The only way I found to do this is creating a redundant Zend_Soap_Client_Common in order to invoke _dorequest. Is really that necessary? Is there any other way to send raw xml to the server?
Here's the code:
$client = new Zend_Soap_Client('http://212.170.239.71/appservices/ws/FrontendService?wsdl',
array(
'soap_version'=>SOAP_1_1
,'encoding' => 'UTF-8'
,'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_DEFLATE
,'location'=>'http://212.170.239.71/appservices/ws/FrontendService'
)
);
$location = 'http://212.170.239.71/appservices/ws/FrontendService';
$request = '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<hb:getHotelValuedAvail xmlns:hb="http://axis.frontend.hydra.hotelbeds.com" xsi:type="xsd:anyType">
<HotelValuedAvailRQ echoToken="DummyEchoToken" sessionId="DummySessionId" xmlns="http://www.hotelbeds.com/schemas/2005/06/messages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.hotelbeds.com/schemas/2005/06/messages HotelValuedAvailRQ.xsd">
<Language>CAS</Language>
<Credentials>
<User>XXXXX</User>
<Password>XXXXX</Password>
</Credentials>
<PaginationData pageNumber="1"/>
<ExtraParamList>
<ExtendedData type="EXT_ORDER">
<Name>ORDER_CONTRACT_PRICE</Name>
<Value>ASC</Value>
</ExtendedData>
</ExtraParamList>
<CheckInDate date="20110809"/>
<CheckOutDate date="20110811"/>
<Destination code="LPA" type="SIMPLE">
<ZoneList>
<Zone code="20" type="SIMPLE"/>
</ZoneList>
</Destination>
<OccupancyList>
<HotelOccupancy>
<RoomCount>1</RoomCount>
<Occupancy>
<AdultCount>2</AdultCount>
<ChildCount>0</ChildCount>
</Occupancy>
</HotelOccupancy>
</OccupancyList>
</HotelValuedAvailRQ>
</hb:getHotelValuedAvail>
</soapenv:Body>
</soapenv:Envelope>';
$clientCommon = new Zend_Soap_Client_Common($client, 'http://212.170.239.71/appservices/ws/FrontendService?wsdl',
array(
'soap_version'=>SOAP_1_1
,'encoding' => 'UTF-8'
,'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_DEFLATE
,'location'=>'http://212.170.239.71/appservices/ws/FrontendService'
));
$response = $client->_doRequest($clientCommon, $request, $location, 'getHotelValuedAvail', SOAP_1_1);
// With these two lines I've managed the call using "native" SoapClient
//$client = new SoapClient("http://212.170.239.71/appservices/ws/FrontendService?wsdl", array('trace'=>1));
//$response = $client->__doRequest($request, $location, 'getHotelValuedAvail', SOAP_1_1);
Thanks in advance.
Jorge