Author Posts

November 14, 2016 at 2:57 pm

I Want to catch all (verbose, errors) from Invoke-Command output
But on my PSv5 Verbose output leaked to host

PS D:\> $o = Invoke-Command -Computername remoteserver { $VerbosePreference = 'Continue'; Write-Verbose 'verb text'; 'out text'  } *>&1
VERBOSE: verb text
PS D:\> $o
out text

Any thoughts how I can make it (except Start-Transcript) ?

November 14, 2016 at 2:58 pm

Well... not quite. Your verbose didn't "leak," you deliberately redirected it to the Output pipeline (1), so your results are exactly as I'd have expected. Is the goal to combine the Verbose and Output pipelines, or no?

November 14, 2016 at 3:06 pm

And incidentally – I'm not sure this is what you're after, so apologies if I'm off-base here – you can't capture multiple streams (output, verbose) to a single variable without merging them. Normally, when you capture the output of Invoke-Command to a variable, you're only going to get the Output pipeline. That's by design. There's no way to "also" capture Verbose, but keep it separate, in a single variable.

November 14, 2016 at 6:11 pm

I'm definitely want to merge output in one variable, and I use *>&1 for it. and it works for local code!
compare this output with above:

PS D:\> $o = Invoke-Command { $VerbosePreference = 'Continue'; Write-Verbose 'verb text'; 'out text'  } *>&1
PS D:\> $o
VERBOSE: verb text
out text

Did you see ? In first example (real remoting) "Verb text" doesn't get catched on $o variable, but displayed on host just before control returned to host.
and on second try (local invoke) it successfully capured in $o variable

and inside we have

PS D:\> $o[0].gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    VerboseRecord                            System.Management.Automation.InformationalRecord


PS D:\> $o[1].gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

that's what I want but can't get for remoting.
I can capture all output with

start-transcript
run code
stop-transcript

but,
1 – have extra file on filesystem,
2 – needed additional parsing for '^VERBOSE:' (I want to send it in html message)
3 – Verbose saved to transcript have line breaks on console buffer width border (80 by default)

November 14, 2016 at 6:16 pm

Have you tried merging the pipelines INSIDE the ScriptBlock, then? That way, the result of Invoke-Command should be what you want?

What you're running into is, when everything runs on the remote computer, it has to get serialized into XML and then deserialized locally. That process is going to affect what you get back.

November 14, 2016 at 6:22 pm

I try to be generic (I need to run vrtually any code and part of it MAY be remote), so I want to stay away of modifying code inside of a scriptblock.

I understand that data searialized forward and back, but why redirection command doesn't work for remote "Verbose" ? the Write-Error works as expected

PS D:\> $o = Invoke-Command -comp remoteserver { $VerbosePreference = 'Continue'; Write-Verbose 'verb text'; 'out text'; write-error 'err text'  } *>&1
VERBOSE: verb text
PS D:\> $o
out text
err text
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
    + PSComputerName        : remoteserver

It looks like a bug

November 14, 2016 at 6:23 pm

I'm afraid I can't answer the "why" on that. It's just how it works.

November 14, 2016 at 6:31 pm

OK, may be I'm ask WHY on github then 🙂

But, Is there any other vay to catch verbose output except for modifying code inside or save transcipt ?

November 14, 2016 at 6:43 pm

For me, that's kind of like asking, "is there any way to make the car go without pushing it or pressing on the gas?" (grinning). That's the way it's designed, so I tend to just stick with what I know works. You can maybe fuss around with running the code -AsJob, since Job objects have different mechanisms for accessing pipelines, but I've never personally run into an instance where I needed that. I honestly tend to not rely much on Verbose output, even, except when I'm developing/debugging. If I'm running code remotely and I need to log things, I create a log. It's a lot easier to retrieve and parse out because I can make my own data structures that way.

November 14, 2016 at 7:03 pm

My best guess would be that those extra streams came along with powershell and the remote mechanism wasn't updated to deal with them, perhaps even depending on the OS/PS version of the remote machine. StdErr is stream 2 and 3+ probably don't work. You could confirm by testing Warning(3) and Debug(5). Also, try a different remote server if the OS of the current one is older.

November 15, 2016 at 4:31 am

@Don, my question looks like "is there any way to make the car go without pushing it or pressing on the gas, because car makers doesn't connect gas pedal ?" :))

the "by design" answer for powershell make me sad, because I always think than powershell have unlimited power...

Yes, I like logs too, but my effors to make universal(for my env.) run&log tool is not only for me, because not all scripts written by me, PS run external tools and so on and I can't install latest ps version everywhere 🙁 thus it's just another way to get maximal information.

@Ron, your prediction about 3+ streams is true, local redirection available since v3+ and remote redirection works only for errors

look closer: -AsJob does not work. stay with transcript