Powershell / XML保存返回值和多个脚本

时间:2018-07-17 15:44:35

标签: xml powershell

我已经编写了XML代码来在Autotask中打开票证,并将其插入到PowerShell脚本中,因为它需要自动化。该脚本创建票证,我需要保存一个创建票证函数返回的值,以便随后可以在同一脚本中对其进行更新。有没有办法

  1. 随后在同一脚本中运行创建票证HTTP POST请求,然后再执行更新请求,并且
  2. 在脚本之间的某个地方保存由创建票证脚本返回的值<id></id>,然后将其用作更新票证脚本中的变量吗?
$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;

标头因包含敏感信息而被故意排除在外。

编辑:这是对请求的回复:

<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>

这只是一块巨大的田野。其中有一个名为<id></id>的字段,其值为整数,这正是我所需要的。

编辑2:
更新的代码

$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;

错误响应:

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

编辑3:

$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;}

1 个答案:

答案 0 :(得分:1)

您可以使用简单的XPath query从响应XML中选择ID。但是请注意,您需要一个名称空间管理器,因为XML数据具有名称空间。我认为响应的属性为ResponseXml,具有已解析的XML数据,但事实并非如此,因此您可能需要这样的东西:

$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'

您还可以使用点访问,在这种特定情况下,这可能是更简单的方法,因为它绕过名称空间并自动扩展叶节点的值:

$rsp = Invoke-WebRequest -Uri $AUTOTASK -Method Post -Body $RequestBody ...
[xml]$xml = $rsp.Content
$id = $xml.Envelope.Body.createResponse.createResult.EntityResults.Entity.id
相关问题