提前道歉,对于这里的理解不够和可能之前已经问过这个问题表示抱歉。我曾经认为通过升级到 Powershell v5.1 就可以解决问题,但是事实证明比我想象的更加复杂,所以我将会更新这个问题。
我们一直在 PS version 4.0 上开发脚本,原因是我们的客户使用的是 Windows 2012 R2 服务器,其标准版本为 PS v4.0。然而,如下所示,这个脚本在 v4.x 上无法正常运行。
这是我的代码,其中包含一个正确格式的 xml 片段。
$NETXNUA = "https://gate.sonile.com/ModSoap";
$ContentType = "text/xml";
# tried this and it this doesn't do anything
# [System.Net.ServicePointManager]::Expect100Continue = $false
$RequestBody = @"
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<sendMessage
xmlns="http://gate.sonile.com/ModSoap" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<application xsi:type="xsd:string">RuFus</application>
<password xsi:type="xsd:string">PingPong</password>
<content xsi:type="xsd:string">Tiddles</content>
<class xsi:type="xsd:string">mt_bubbles</class>
</sendMessage>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
"@
try {
$what = Invoke-WebRequest -Uri $NETXNUA -Method Post -Body $RequestBody -ContentType $ContentType -UseBasicParsing;
}
catch {
If ($_.Exception.Response.StatusCode.value__) {
$crap = ($_.Exception.Response.StatusCode.value__ ).ToString().Trim();
Write-Output "crap $crap";
}
If ($_.Exception.Response.StatusDescription) {
$crapdescription = ($_.Exception.Response.StatusDescription).ToString().Trim();
Write-Output "crapdesc $crapdescription";
}
If ($_.Exception.Message) {
$crapMessage = ($_.Exception.Message).ToString().Trim();
Write-Output "crapmsg $crapMessage";
}
If ($_.ErrorDetails.Message) {
$ResponseBody = ($_.ErrorDetails.Message).ToString().Trim();
$ResponseBody = $ResponseBody -replace "\s+", " ";
}
Write-Output "default $ResponseBody";
}
当我在标准的Powershell中运行此脚本时,以下是发生的情况:
操作系统为Windows 8.1 Pro
Name Value
---- -----
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.42000
BuildVersion 6.3.9600.17400
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
以下是结果,注意"$_.Exception.Message"是唯一有值的项。
crapmsg '"utf-8"' is not a supported encoding name. For information on
defining a custom encoding, see the documentation for the Encoding.Regi
sterProvider method.
Parameter name: name
换句话说,这是一个可悲的失败,但不管信不信,主机处理了帖子数据。
现在,在更新的v5.1 Powershell下,将完全相同的脚本运行在Windows Server 2008 R2上。
Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
下面是从"$_.Exception.Message"得到的结果:
crapmsg Value cannot be null.
Parameter name: name
哇,这有些不同,发生了什么事情..?
那么,让我们在安装了 Powershell v5.1 更新的 Windows Server 2012 R2 Azure VM 上再次尝试相同的脚本。
Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
同样的结果,和2008 R2服务器一样,只有"$_.Exception.Message"返回了内容。至少这是一致的,因为PS版本是相同的。
crapmsg Value cannot be null.
Parameter name: name
我可以尝试在Windows系列中的流浪汉Windows 10 Home版上安装标准的Powershell v5.1来测试这个脚本。
Name Value
---- -----
PSVersion 5.1.14393.1358
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.1358
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
哇,我简直不敢相信……这是个奇迹!它能够完美地工作,并返回一个200响应和一个XML格式的主机响应,我可以对其进行处理。
StatusCode : 200
StatusDescription : OK
Content : <?xml version="1.0" encoding="UTF-8"?>
<tns1:Envelope
xmlns:tns1="http://schemas.xmlsoap.org/soap/envelope/">...etc
RawContent : HTTP/1.1 200 OK
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Length: 411
Content-Type: text/xml; charset="utf-8"
Date: Thu, 06 Jul 2017 04:02:15 GMT
Server: Apache
Via: 1.1 ga...
Forms :
Headers : {[Keep-Alive, timeout=15, max=100], [Connection, Keep-
Alive], [Content...etc
Images : {}
InputFields : {}
Links : {}
ParsedHtml :
RawContentLength : 411
如果我的客户能够放弃他们喜欢的麻烦的Windows服务器,改用Windows 10,那么一切都会彻底解决!
最新消息!刚试用了Windows Server 2016 Azure VM,也可以正常使用。
Name Value
---- -----
PSVersion 5.1.14393.479
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.479
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
是否有某个秘密参数可以使此脚本在各种平台和版本的PowerShell上正常工作?
我创建的所有其他使用Invoke-WebRequest的脚本都在PS v4和v5上正常工作,只有这个脚本出现了问题。
非常感谢任何提示。
之前我尝试使用文件输入来读取xml,像这样使用-InFile...
Invoke-WebRequest "https://gateway.mobil.com/MSoap" -Method Post -ContentType "text/xml" -InFile "C:\Scripts\mobil.xml" -OutFile "C:\PWScripts\mobil_out.xml"
那个方法可以,但对于我的应用程序来说不太合适。
$ContentType
里面是什么?你能包含一下填充它的代码吗? - Patrick Meinecke"application/xml"
可能会正确处理标头,以及此帖子,详细介绍如何将PowerShell的Unicode
编码文本转换为UTF8
。 - G42