【问题标题】:Putting a SOAP request in a here-string将 SOAP 请求放入此处的字符串中
【发布时间】:2013-03-24 02:59:48
【问题描述】:

我正在尝试编写一个脚本,该脚本将发送随机 SOAP 请求以测试另一个进程。但是我似乎无法创建变量。每次我将代码从记事本复制/粘贴到 PS 控制台时,脚本都会以 >> 结尾(即使在多次按 Enter 后也是如此)。即使我只复制/粘贴脚本的$SOAPRequest 部分,也会发生同样的事情。如果我注释掉整个 here-string,脚本就会运行(尽管由于缺少 SOAP 内容而出现错误)。

我尝试了以下各种组合:

  • 用反斜杠转义英镑符号
  • 删除包含井号的行
  • 在 Powershell v1 和 Powershell v2 中使用 SOAP 请求创建变量
  • 删除所有带有 http 地址的行
  • 使用@''@(不仅没用还需要变量扩展)

问题:如何让 Powershell 将 here-string 中的内容设置为 $SOAPRequest 变量?换句话说,我怎样才能停止>>?通常这意味着我错过了括号、括号或双引号,但我似乎找不到类似的东西。我不知道为什么这不起作用。

我寻求帮助的页面:

$SOAPRequest 变量:

$SOAPRequest = [xml] @"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soa="http://bmc.com/ao/xsd/2008/09/soa">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>USER</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">#PASSWD#</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<soa:executeProcess>
<soa:gridName>GRID</soa:gridName>
<soa:processName>Software_Distribution</soa:processName>
<soa:parameters>
<soa:Input>
<soa:Parameter>
<soa:Name required="true">Software Request</soa:Name>
<soa:Value soa:type="xs:anyType">
<soa:XmlDoc>
<request>
<Source>SourceName</Source>
<Command>create</Command>
<Debug>true</Debug>
<DeployType>standard</DeployType>
<PkgId>$pkgID</PkgId>
<PackageName>$pkgName</PackageName>
<PackageShareLocation>\\Network\Share\With\Content</PackageShareLocation>
<PackageFormat>exploded</PackageFormat>
<InstallScript>install.bat</InstallScript>
<InstallTimeout>3600</InstallTimeout>
<SilentInstall>True</SilentInstall>
<Emails />
</request>
</soa:XmlDoc>
</soa:Value>
</soa:Parameter>
</soa:Input>
</soa:parameters>
</soa:executeProcess>
</soapenv:Body>
</soapenv:Envelope>
"@

尽管这个问题似乎与这里的字符串特别相关,但这是上下文脚本的其余部分:

#----------------------------------------------------------------------
# Variables
#----------------------------------------------------------------------
$pkgID = 346
$pkgNameList = @("Package_ABC", "Package_DEF", "Package_XYZ", "Package_123" )

#Set start/end datestamps
$now= Get-Date
$end = Get-Date "04/03/2013 08:00 AM"


$testDirectory = "C:\Users\UserName\Desktop\AutomatedSOAPTest"
if (!(Test-Path $testDirectory)){
    New-Item $testDirectory -itemType directory | Out-Null
}

#----------------------------------------------------------------------
# Functions
#----------------------------------------------------------------------
#Function to write to SOAP request log
function Write-Log($message)
{
    $logDate = Get-Date -format "MM/dd/yy HH:mm:ss"
    $logPath = "$testDirectory\progress.log"

    Write-Output "$logDate $message" | Out-File -FilePath $logPath -Append
}#end Write-Log function

#Function to write to SOAP return log
function Write-Return($xml, $item)
{
    $logDate = Get-Date -format "MM/dd/yy HH:mm:ss"
    $logPath = "$testDirectory\SOAP_return-$item.log"

    $success = $xml.status.success
    $message = $xml.status.message

    Write-Output "Request returned for $item on $logDate" | Out-File -FilePath $logPath -Append
    Write-Output "Success: $success" | Out-File -FilePath $logPath -Append
    Write-Output $message | Out-File -FilePath $logPath -Append
}#end Write-Log function

#Function to call SOAP request
function Execute-SOAPRequest(
    [Int]    $pkgID,
    [String] $pkgName
)
{
    $SOAPRequest = [xml] @"
        <SOAP request content here>
    "@

    $SOAPurl = "http://<site where requests are sent>"

    Write-Log "Sending SOAP Request for $pkgName To Server: $SOAPurl"
    $soapWebRequest = [System.Net.WebRequest]::Create($SOAPurl)
    $soapWebRequest.Headers.Add("SOAPAction","`"`"")

    $soapWebRequest.ContentType = "text/xml;charset=`"utf-8`""
    $soapWebRequest.Accept      = "text/xml"
    $soapWebRequest.Method      = "POST"

    Write-Log "Initiating Send."
    $requestStream = $soapWebRequest.GetRequestStream()
    $SOAPRequest.Save($requestStream)
    $requestStream.Close()

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

    Write-Log "Response Received."

    Write-Return $ReturnXml.status.success
    Write-Return $ReturnXml.status.message
}#End Execute-SOAPRequest function

#----------------------------------------------------------------------
# Code
#----------------------------------------------------------------------

while($now -lt $end)
{
    $pkgList = Get-Random -input $pkgNameList -count 4

    foreach($pkgName in $pkgList)
    {
        #Run function to execute SOAP request
        Execute-SOAPRequest $pkgID $pkgName

        $pkgID++
    }

    Start-Sleep -s 3600
    $now = Get-Date
}

Execute-SOAPRequest 函数的代码来自这里:http://www.iislogs.com/steveschofield/execute-a-soap-request-from-powershell

【问题讨论】:

    标签: xml powershell soap


    【解决方案1】:

    此处字符串中的终止“@”必须从第 1 列开始。

    当您将它粘贴到代码中时,它会出现,它被缩进,并且缩进中的前导空格导致解析器继续读取以下代码作为 here-string 的一部分。由于字符串从未正确终止,>> 提示输入此处字符串的更多数据,或终止的 "@.

    编辑:如果您不想弄乱 Process 块中的缩进,您可以将可扩展的 here-string 作为脚本块移动到 Begin 块中,稍后再调用它:

    Begin{
    $SoapString = {
    @"
    This is my here-string containing $variable
    "@
    }
    }
    
    
    Process{
    $variable = "MY VARIABLE"
    
      foreach ($x in 1)
       {
         &$SoapString
        }
    }
    
    
    This is my here-string containing MY VARIABLE
    

    如果你不喜欢它在脚本的头部混乱,如果你愿意,你可以把 Being 块放在底部。 Powershell 仍然会按照 Begin、Process、End 的顺序运行它们,无论它们在脚本中的顺序是什么:

    Process{
    $variable = "MY VARIABLE"
    
      foreach ($x in 1)
       {
         &$SoapString
       }
    }
    
    Begin{
    $SoapString = {
    @"
    This is my here-string containing $variable
    "@
    }
    }
    
    This is my here-string containing MY VARIABLE
    

    【讨论】:

    • 太好了,我没有意识到这里字符串的打开和关闭必须从第 1 列开始。谢谢!
    • 开头不必,但结尾必须。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    相关资源
    最近更新 更多