6

I am trying to store output from Invoke-expression into a variable as well as on screen. I have PS logging which automatically log everything as Write-Host in a file. Now I am using Invoke-Expression which seems to either print the output on Screen or to a variable, I need both

All that I have tried is:

$var = "C:\ER\work\Canny.exe -Init ER\ER2 Get-ip"

$val = Invoke-Expression $var

This doesn't print anything on Screen so I am unable to know if there are any issues while running. I later do a Write-Host of $val which logs it but its sometimes too late to know what happened If I use:

Invoke-Expression $var

Nothing is logged (obviously), but there is console output and if I want to see after sometime for logs what happened, I have no way of Investigating. I have also tried :

Invoke-Expression $var -OutVariable out 

OR

Invoke-Expression $var -OutVariable $out 

This is of no use here. I have also created a script block and tried with

Invoke-Command 

but again of no use I just need it to print the output on Screen as well as to a variable.

Frode F.
  • 52,376
  • 9
  • 98
  • 114
Akshay
  • 91
  • 1
  • 1
  • 5

2 Answers2

13

Invoke-Expression -Command $var -OutVariable out should work (variable + console output), but there's something weird going on. It works in ISE, but in a normal PowerShell console I get an empty ArrayList. If you pipe it to another command like Out-String it works (but this would return a single multi-line string).

Invoke-Expression -Command $var | Out-String -OutVariable out

Either I'm forgetting something or it might be a bug with Invoke-Expression.

A workaround would be to use Tee-Object which behaves the same as -OutVariable.

The Tee-Object cmdlet redirects output, that is, it sends the output of a command in two directions (like the letter "T"). It stores the output in a file or variable and also sends it down the pipeline. If Tee-Object is the last command in the pipeline, the command output is displayed at the prompt.

Example:

Invoke-Expression $var -OutVariable | Tee-Object -Variable out 

or (to a file):

Invoke-Expression $var -OutVariable | Tee-Object -FilePath c:\text.txt

Be aware that it overwrites the content in $out.

Frode F.
  • 52,376
  • 9
  • 98
  • 114
2

This is where the cmdlet Tee-Object comes in handy. You can pipe your Invoke-Command to it, and specify if you want to store the output as a variable or a file, and it will both store the data as you specify, as well as pass it down the pipe (to be output to screen, if that is what you want).

Invoke-Expression $var | Tee-Object C:\Path\To\File.txt
TheMadTechnician
  • 34,906
  • 3
  • 42
  • 56
  • This starts my Exe to fail: – Akshay May 19 '16 at 18:15
  • invoke-expression $expr ; works well, Invoke-Expression $var | Tee-Object -Variable xyz ; exe gives System.NullReferenceException: Object reference not set to an instance of an object – Akshay May 19 '16 at 18:16
  • I see that you found a solution, but I'm guessing that `(Invoke-Expression $var) | Tee-Object -Var xyz` would probably work, but that's going to make the executable finish its output before it tries to pass the info down the pipe. – TheMadTechnician May 20 '16 at 17:56