Apologies in advance for the lack of understanding here and the possibility this question has been asked before. Having thought I got it sorted by moving to Powershell v5.1 it turns out to be more complicated than I thought so I'll update the question.
We have been developing scripts on PS version 4.0 for the explicit reason that our customers have Windows 2012 R2 servers on which PS v4.0 is standard. However, this script doesn't run properly on v4.x as shown below
Here is my code with a correctly formed xml snippet
$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";
}
This is what happens when I run this script on Windows 8.1 Pro and standard Powershell
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
Below is the result, note that "$_.Exception.Message" is the only item with any value in it
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
In other words, a miserable failure, except believe it or not, the Host processed the post data
Now run this exact same script on a Windows Server 2008 R2 with updated v5.1 Powershell
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
and here is the result below from "$_.Exception.Message"
crapmsg Value cannot be null.
Parameter name: name
Woah, that's different, what's going on here..?
Right then, let's try this exact same script again on a Windows Server 2012 R2 Azure VM with a Powershell v5.1 update
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
Well now, same result as on the 2008 R2 server with only "$_.Exception.Message" returning anything. At least that's consistent, which figures because the PS versions are the same.
crapmsg Value cannot be null.
Parameter name: name
What about I try this script on the ragamuffin of the Windows collection Windows 10 Home edition with standard installed 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
OMG, I don't believe it... a miracle! It works perfectly with a 200 response returned in $what plus the Host response in xml that I can process.
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
Everything would be totally sorted, if only my customers would throw out those pesky Windows Servers they favour and use Windows 10 instead..!
Breaking News! Just tried Windows Server 2016 Azure VM and that works fine too.
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
Is there some secret parameter that would enable this script to work properly on various platforms and versions of Powershell...?
Every other script I've created using Invoke-WebRequest has worked just fine on PS v4 & v5 it's just this one that is causing problems.
Any tips at all gratefully accepted
Previously I tried using a file input for the xml and reading with -InFile like this...
Invoke-WebRequest "https://gateway.mobil.com/MSoap" -Method Post -ContentType "text/xml" -InFile "C:\Scripts\mobil.xml" -OutFile "C:\PWScripts\mobil_out.xml"
That worked fine, but it isn't suitable for my application
Having toiled on this script all week for countless hours... bizarrely, it only ever bombed out on a successful 200 status return, errors were returned just fine!
Turns out that Invoke-WebRequest has an insurmountable problem acknowledged as posted by @vane in April 2016 Why is Invoke-WebRequest and Invoke-RestMethod failing and succeeding at the same time?
Therefore, please correct me if I'm wrong, the only known solution is to revert to a standard http WebRequest call something like this (wrap it with your own error handling);
$encodedContent = [System.Text.Encoding]::UTF8.GetBytes($RequestBody)
$webRequest = [System.Net.WebRequest]::Create($NETXNUA)
$webRequest.Method = "Post"
$webRequest.ContentType = $ContentType
$webRequest.ContentLength = $encodedContent.length
$requestStream = $webRequest.GetRequestStream()
$requestStream.Write($encodedContent, 0, $encodedContent.length)
$requestStream.Close()
[System.Net.WebResponse] $response = $webRequest.GetResponse();
I have verified this older style mechanism works perfectly on the following platforms;
Win 8.1 Pro with PS v4.0
Server 2008 R2 with PS 5.1
Server 2012 R2 with PS 5.1 (Azure VM)
Server 2012 R2 with PS v4.0 (Azure VM)
Win 10 Home with PS 5.1
Server 2016 with PS v5.1 (Azure VM)
I acknowledge that Invoke-WebRequest script worked flawlessly on Win 10 and Server 2016, so eventually the problem will just go away!
TWO YEARS LATER, NOVEMBER 2019: BIZARRE DISCOVERY..!
Updated a device to Windows 10 version 1903 and set about getting scripts going.
Immediately discovered any script using Invoke-WebRequest didn't work.
Error was caused by install of Internet Explorer not being completed.
Installed IE, Invoke-WebRequest runs fine.
MORAL: You can never quite escape IE completely
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With