9

Using PowerShell 4.0 and Invoke-RestMethod cmdlet. I'm having trouble with the -OutFile and -PassThru options. Whenever I add the -PassThru option, my -OutFile is created but the contents are Empty!

According to the Invoke-RestMethod Documentation, both an output file and pipeline object should be available when these options are used together. "-OutFile Saves the response body in the specified output file. [...] To send the results to a file and to the pipeline, use the Passthru parameter."

Here's a test to repeat the problem I'm having. Here I'm calling a rest api attempting to BOTH save response to file AND deserialize into a powershell object.

"POWERSHELL VERSION $($host.Version.ToString())"
$date = Invoke-RestMethod "http://date.jsontest.com" -OutFile "OutFile.txt" -PassThru
Get-Content "OutFile.txt"
# FILE IS EMPTY!!! PASSTHRU SEEMS TO RESULT IN EMPTY FILE
$date
# powershell object has the date received from api

Here are two tests to verify the normal functionality of Invoke-RestMethod WITHOUT the PassThru option

# ... Test # 1, call rest api and deserialize into powershell object
$date = Invoke-RestMethod "http://date.jsontest.com"
$date
# Output shows the date retrieved from sample restful service
# ... Test # 2, call rest api and save response body directly to a file
Invoke-RestMethod "http://date.jsontest.com" -OutFile "OutFile.txt"
Get-Content "OutFile.txt"
# Output shows contents of rest api response body (json text)

I think these tests should help others see the trouble I'm having. My question is whether there is something I'm missing to make this work, or whether this may be a bug with the cmdlet? I've Googled a bit for solution and no obvious reports of this issue. I'm wanting to use -OutFile as part of a workaround for another Invoke-RestMethod issue related to content encoding as described at Bug? Invoke-RestMethod and UTF-8 data. The -PassThru option is helpful for me to look at the returned data and terminate iteration on a multi-request (paged) odata result set.

Mister_Tom
  • 1,500
  • 1
  • 23
  • 36
  • You could `Tee-Object` – BenH Mar 24 '17 at 21:24
  • Thanks @BenH, unfortunately I'm currently using something like Tee, but there's a [character encoding bug I'm trying to resolve](https://social.technet.microsoft.com/Forums/office/en-US/d795e7d2-dcf1-4323-8e06-8f06ce31a897/bug-invokerestmethod-and-utf8-data?forum=winserverpowershell) that appears to have a workaround requiring -OutFile to be used directly on Invoke-RestMethod cmdlet. – Mister_Tom Mar 24 '17 at 21:27
  • 1
    `Invoke-RestMethod` wraps `Invoke-WebRequest`, which derives from `WebRequestPSCmdlet`. [That code has variables called](https://github.com/PowerShell/PowerShell/blob/b043b444db58801ca98bd72f3242a55bb4b8234b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs#L465) `ShouldSaveToOutFile` which checks if you've provided a filename, and `ShouldWriteToPipeline` as `(!ShouldSaveToOutFile || PassThru)`. Looks like it's intended to work as you think. File if you named one, else pipeline. Both if you used outfile and passthru. – TessellatingHeckler Mar 24 '17 at 22:42
  • 1
    And [the output code has](https://github.com/PowerShell/PowerShell/blob/b043b444db58801ca98bd72f3242a55bb4b8234b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeRestMethodCommand.FullClr.cs#L37) separate checks for `if (ShouldWriteToPipeline)` and `if (ShouldSaveToOutFile)`. These links are for PSv6 open source code... so could also have been a bug in v4 and fixed. – TessellatingHeckler Mar 24 '17 at 22:45
  • I just tested on PowerShell 5.1 on Windows 10 - same problem using same test above. I appreciate the code samples and analysis from @TessellatingHeckler - is there a date announced for production release of PowerShell 6.0? I would love to test it, but probably after it goes RTM. – Mister_Tom Mar 25 '17 at 02:24
  • 1
    No idea about a date for PS 6. I've just tried it on Windows 10 PS 5.1 as well, and Invoke-WebRequest can do -Outfile and -PassThru together, but Invoke-RestMethod can't. Weird. Regarding your encoding bug link, I just found a random REST API online which echos what you send it, and tried `irm https://httpbin.org/get?q=1♫` and the musical note comes back in the console. The headers it sends back have `Content-Type: application/json`. Another one `irm http://httpbin.org/encoding/utf8` sends `Content-Type: text/html; charset=utf-8` header and unicode comes through OK. If your REST said utf8... – TessellatingHeckler Mar 25 '17 at 07:31
  • Thanks @TessellatingHeckler. That's another problem I'm having, no supported access to response headers with Invoke-RestMethod. Looks like I'll be using Invoke-WebRequest for more of these REST tasks so I can see the headers returned and maybe respond better to missing or incorrect content-type from 3rd party web service responses. I'll keep an eye out for PS 6 RTM to see if this gets fixed :-). – Mister_Tom Mar 26 '17 at 23:57
  • That seems to be a bug in the command. You can try this: `Invoke-RestMethod "http://date.jsontest.com" -PassThru -OutFile .\Out2.txt | Out-File .\Out.txt` – SavindraSingh Jul 09 '18 at 11:05

1 Answers1

1

I believe the -PassThru switch redirects all output to the console only, and I think that is why your file is empty. However, since you have it a variable you could add one more line like so. . .

Write-Output -InputObject $date | Out-File -FilePath "OutFile.txt"