4

I need help understanding a strange output behavior when using the exit statement and pscustomobject.

Example, script.ps1:

'hello'
[pscustomobject]@{'foo'='bar'}
'world'
exit 123

Calling the script: powershell -file script.ps1

Only hello will be returned. Versions 5.1 and 7.1 both behave like this. Can it be explained, or is this something for the github guys to fix?

Edit, based on comments: Running it from within Powershell, it works as expected. Calling PowerShell with -Command .\script.ps1 it also works (the exit code is gone, though).

It is this combination that breaks the output: Using the exit statement and calling PowerShell with -File.

Thanks

Palansen
  • 311
  • 2
  • 7
  • Can you try to wrap it in the *sub-expression* operator? `$([pscustomobject]@{'foo'='bar'}) | Out-Default`. I think I have an idea, just wanna confirm. – Abraham Zinala Oct 03 '21 at 15:35
  • 2
    @AbrahamZinala, i just tested your theory and it does work, but then i removed the `$()` and it still worked as ```[pscustomobject]@{'foo'='bar'} | Out-Default```, so its as if the the expression is never being sent to stdout? – Otter Oct 03 '21 at 15:39
  • Why dont you assign the pscustomobject to a variable? $mytest = [pscustomobject]@{'foo'='bar'} and everything runs fine. $myTest = [pscustomobject]@{'foo'='bar'} [console]::writeline($myTest) also runs fine – Farbkreis Oct 03 '21 at 15:48
  • This almost certainly has to do with `pscustomobject` vs `psobject` (it works with psobject), i just cant figure out why yet! Take a look at [this](https://stackoverflow.com/a/50196654/16106482) link to learn more about them. > PSCustomObject isn't an object type per se – it's a process shortcut. – Otter Oct 03 '21 at 15:58
  • @otter, to summarize, the call to `exit` beats the pipeline output to the formatting system; which PowerShell bases the execution off of. This is why using just the sub-expression alone should work, but so would any formatting cmdlets. Take a look at mklements answer [here](https://stackoverflow.com/a/43691123/14903754). So yes, it doesn't make it doesn't make it to *stdout*. – Abraham Zinala Oct 03 '21 at 16:08
  • I ran into this issue before where my `Read-Host` kept coming before my `PSCustomObject`. – Abraham Zinala Oct 03 '21 at 16:12
  • 1
    You are right! Putting sleeps of a second between each line worked fine (lower than a second failed). Can't say I'm a fan of this behaviour but i understand it. Can you put it in as the answer so @palansen can accept it? – Otter Oct 03 '21 at 16:15
  • 1
    Yeah man, I'm not fan of that either lol. Ehh, I'll just flag it as a duplicate. – Abraham Zinala Oct 03 '21 at 16:21
  • Inserting a sleep seems to "fix" it, but it differes from what mklement0 talks about. In this case, all objests are emitted to the pipeline - so they should be processed in correct order. And keep in mind: It only happens when you call powershell from an external application - and using -File and the exit statement. – Palansen Oct 03 '21 at 17:24
  • You're calling a file, not the commands individually. PowerShell.exe will not change it's rules just because it's being called from cmd.exe. – Abraham Zinala Oct 03 '21 at 18:34
  • What rule is that? mklement0 is talking about emitting objects + calling Write-Host, where objects are displayed out of order. It is very different from this problem - where objects are not displayed/returned at all - when the script is executed under a specific condition. – Palansen Oct 03 '21 at 19:14
  • 1
    Please re-read his explanation and not just the code snippet, that was just his examples of what was happening. Not the actual answer itself. – Abraham Zinala Oct 03 '21 at 19:43
  • 1
    You are right. And it seems that calling exit within 300 ms of outputting the pscustomobject just terminates the script without outputting anything. I'm almost happy now. Thanks. :) – Palansen Oct 03 '21 at 21:00

0 Answers0