Reputation: 11
I've written XML code to open a ticket in Autotask and inserted it into a PowerShell script because it needs to be automated. The script creates a ticket and I need to save a value that the create ticket function returns so I can then update it in the same script. Is there a way to
<id></id>
that is returned by the create ticket script, and then use it as a variable in the update ticket script?$RequestBody = @"
<?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:Header>
<AutotaskIntegrations xmlns="http://autotask.net/ATWS/v1_5/">
</AutotaskIntegrations>
</soap:Header>
<soap:Body>
<create xmlns="http://autotask.net/ATWS/v1_5/">
<Entities>
<Entity xsi:type="Ticket" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
all my entities
</Entity>
</Entities>
</create>
</soap:Body>
</soap:Envelope>
"@
Invoke-WebRequest -Uri $AUTOTASK -Method Post -Body $RequestBody -ContentType $ContentType -UseBasicParsing -Headers $Headers;
$id = @"<id/>"@ # The field I want to save and insert later is returned as <id></id>
$UpdateBody = @"
<?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/">
<soap:Header>
<AutotaskIntegrations xmlns="http://autotask.net/ATWS/v1_5/">
</AutotaskIntegrations>
</soap:Header>
<soap:Body>
<update xmlns="http://autotask.net/ATWS/v1_5/">
<Entities>
<Entity xsi:type="Ticket" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
all my entities
<id>$id</id>
</Entity>
</Entities>
</update>
</soap:Body>
</soap:Envelope>
"@
Invoke-WebRequest -Uri $AUTOTASK -Method Post -Body $UpdateBody -ContentType $ContentType -UseBasicParsing -Headers $Headers;
The headers were left out on purpose due to them containing sensitive info.
EDIT: Here is the response to the request:
<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>
<createResponse xmlns="http://autotask.net/ATWS/v1_5/">
<createResult>
<ReturnCode>1</ReturnCode>
<EntityResults>
<Entity xsi:type="Ticket">
<id>12345</id>
<UserDefinedFields>
<UserDefinedField><Name>Escalated Internally?</Name></UserDefinedField>
<UserDefinedField><Name>Ticket Category</Name></UserDefinedField>
<UserDefinedField><Name>Escalated by Customer?</Name></UserDefinedField>
<UserDefinedField><Name>Initial Severity</Name></UserDefinedField>
<UserDefinedField><Name>Incident Start Date/Time</Name></UserDefinedField>
</UserDefinedFields>
</Entity>
<!-- etc. -->
</EntityResults>
</createResult>
</createResponse>
</soap:Body>
</soap:Envelope>
It's just a giant block of fields. In there is a field called <id></id>
whose value is an integer, which is what I need.
EDIT 2:
Updated Code
$RequestBody = @"
<?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:Header>
<AutotaskIntegrations xmlns="http://autotask.net/ATWS/v1_5/">
</AutotaskIntegrations>
</soap:Header>
<soap:Body>
<create xmlns="http://autotask.net/ATWS/v1_5/">
<Entities>
<Entity xsi:type="Ticket" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AccountID>123</AccountID>
<Active>123</Active>
<DueDateTime>09/30/18</DueDateTime>
<Title>$Title</Title>
<Status>123</Status>
<Priority>123</Priority>
<QueueID>123<QueueID>
<InstalledProductID>123</InstalledProductID>
</Entity>
</Entities>
</create>
</soap:Body>
</soap:Envelope>
"@
$rsp = Invoke-WebRequest -Uri $AUTOTASK -Method Post -Body $RequestBody -ContentType $ContentType -UseBasicParsing -Headers $Headers;
$ticketno = $rsp.ResponseXml.Envelope.Body.createResponse.createResult.EntityResults.Entity.id;
$UpdateBody = @"
<?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/">
<soap:Header>
<AutotaskIntegrations xmlns="http://autotask.net/ATWS/v1_5/">
</AutotaskIntegrations>
</soap:Header>
<soap:Body>
<update xmlns="http://autotask.net/ATWS/v1_5/">
<Entities>
<Entity xsi:type="Ticket" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AccountID>123</AccountID>
<Title>Success</Title>
<Status>123</Status>
<Priority>123</Priority>
<id>$ticketno</id>
<DueDateTime>09/30/18</DueDateTime>
<QueueID>123</QueueID>
</Entity>
</Entities>
</update>
</soap:Body>
</soap:Envelope>
"@
Invoke-WebRequest -Uri $AUTOTASK -Method Post -Body $UpdateBody -ContentType $ContentType -UseBasicParsing -Headers $Headers;
Error response:
Invoke-WebRequest : soap:ClientSystem.Web.Services.Protocols.SoapException: Server was unable to read request. ---> System.InvalidOperationException: There is an error in XML document (15, 20). ---> System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) at System.Int64.Parse(String s, NumberStyles style, IFormatProvider provider) at System.Xml.XmlConvert.ToInt64(String s) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read201_Ticket(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read5_Entity(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read253_update() at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer44.Deserialize(XmlSerializationReader reader) at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) --- End of inner exception stack trace --- at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle) at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters() --- End of inner exception stack trace --- at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters() at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest() At C:\Users\Marc\Documents\StoredValue.ps1:86 char:1 + Invoke-WebRequest -Uri $AUTOTASK -Method Post -Body $UpdateBody -Cont ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (Method: POST, R...pe: text/xml}:HttpRequestMessage) [Invoke-WebRequest], HttpResponseException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
EDIT 3:
Result of $rsp | Get-Member
TypeName: Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() BaseResponse Property System.Net.Http.HttpResponseMessage BaseResponse {get;set;} Content Property string Content {get;} Encoding Property System.Text.Encoding Encoding {get;} Headers Property System.Collections.Generic.Dictionary[string,System.Collections.Generic.IEnumerable[string]] Headers {get;} Images Property Microsoft.PowerShell.Commands.WebCmdletElementCollection Images {get;} InputFields Property Microsoft.PowerShell.Commands.WebCmdletElementCollection InputFields {get;} Links Property Microsoft.PowerShell.Commands.WebCmdletElementCollection Links {get;} RawContent Property string RawContent {get;set;} RawContentLength Property long RawContentLength {get;} RawContentStream Property System.IO.MemoryStream RawContentStream {get;} RelationLink Property System.Collections.Generic.Dictionary[string,string] RelationLink {get;} StatusCode Property int StatusCode {get;} StatusDescription Property string StatusDescription {get;}
Upvotes: 0
Views: 871
Reputation: 200473
You can select the ID from the response XML with a simple XPath query. Note that you need a namespace manager, though, because the XML data has namespaces. I thought the response had a property ResponseXml
with the already parsed XML data, but that doesn't seem to be the case, so you probably need something like this:
$rsp = Invoke-WebRequest -Uri $AUTOTASK -Method Post -Body $RequestBody ...
[xml]$xml = $rsp.Content
$nm = New-Object Xml.XmlNamespaceManager $xml.NameTable
$nm.AddNamespace('ns', 'http://autotask.net/ATWS/v1_5/')
$id = $xml.SelectSingleNode('//ns:id', $nm).'#text'
You could also use dot-access, which in this particular scenario is probably the simpler approach, because it bypasses namespaces and auto-expands the value of the leaf node:
$rsp = Invoke-WebRequest -Uri $AUTOTASK -Method Post -Body $RequestBody ...
[xml]$xml = $rsp.Content
$id = $xml.Envelope.Body.createResponse.createResult.EntityResults.Entity.id
Upvotes: 1