3

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

rangi
  • 361
  • 2
  • 4
  • 21
  • 1
    What's in `$ContentType`? Can you include the code where that is populated? – Patrick Meinecke Jul 01 '17 at 11:14
  • To add to @PatrickMeinecke's comment: What do you get instead of an error? What does `$what` contain? – G42 Jul 01 '17 at 14:10
  • Thanks for your interest @PatrickMeinecke and I've added the $ContentType to my question – rangi Jul 01 '17 at 19:42
  • 1
    @rangi Nice debugging. Check out [this post](https://stackoverflow.com/a/10179724/5039142) which suggests `"application/xml"` may result in header being dealt with correctly, and [this post](https://stackoverflow.com/a/15299432/5039142) that details how to turn PowerShell's `Unicode`-encoded text to `UTF8` – G42 Jul 02 '17 at 23:18
  • Thanks @gms0ulman Imagine our surprise when we chucked it on v5 and it worked..! Will investigate your suggestions – rangi Jul 03 '17 at 01:28
  • Seems there might be is an unresolvable issue here as posted by @vane – rangi Jul 09 '17 at 03:52

1 Answers1

2

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

rangi
  • 361
  • 2
  • 4
  • 21