Powershell: Invoke-Expression and Tee-Object

So in my previous post I wrote about how I got around a problem with some standard error from Perforce. I want to take my work around function and pipe it into Tee-object so I can simultaneously display and log what’s going on with the execution of my consistency check. A consistency check could take a while, so being able to see it’s running output is important.

In my function, I use Invoke-Expression. Well, turns out it’s not so easy to just pipe that into Tee-Object. At least in PSH V1.

Here is my test PowerShell script:

write-host Running in PowerShell Version $host.version.major
write-host 'Executing: Invoke-Expression "print.exe /?" | tee-object -filepath test.log'
Invoke-Expression "print.exe /?" | tee-object -filepath test.log
write-host Now lets get the content of test.log
get-content test.log
write-host
write-host 'Executing: Invoke-Expression "print.exe /?" > test.log'
Invoke-Expression "print.exe /?" > test.log
write-host Now lets get the content of test.log 
get-content test.log

Run it inside PowerShell v1:

PS C:\temp> .\test.ps1
Running in PowerShell Version 1
Executing: Invoke-Expression "print.exe /?" | tee-object -filepath test.log
Prints a text file.
 
PRINT [/D:device] [[drive:][path]filename[...]]
 
   /D:device   Specifies a print device.
 
Now lets get the content of test.log
Get-Content : Cannot find path 'C:\temp\test.log' because it does not exist.
At C:\temp\test.ps1:5 char:12
+ get-content  <<<< test.log
 
Executing: Invoke-Expression "print.exe /?" > test.log
Now lets get the content of test.log
Prints a text file.
 
PRINT [/D:device] [[drive:][path]filename[...]]
 
   /D:device   Specifies a print device.

The pipe doesn’t work, but standard redirection does. I also tried piping it to out-file. Oddly, the output goes straight to the screen and nothing to the file.

Now let’s try it in v2 CTP3:

PS C:\temp> .\test.ps1
Running in PowerShell Version 2
Executing: Invoke-Expression "print.exe /?" | tee-object -filepath test.log
Prints a text file.
 
PRINT [/D:device] [[drive:][path]filename[...]]
 
   /D:device   Specifies a print device.
 
Now lets get the content of test.log
Prints a text file.
 
PRINT [/D:device] [[drive:][path]filename[...]]
 
   /D:device   Specifies a print device.
 
 
Executing: Invoke-Expression "print.exe /?" > test.log
Now lets get the content of test.log
Prints a text file.
 
PRINT [/D:device] [[drive:][path]filename[...]]
 
   /D:device   Specifies a print device.
 
PS C:\temp>

In v2, we get the expected result.

I was about to give up on this, but I found this post that describes basically the same issue. The suggested fix is to wrap the Invoke-Expression (or iex) in parenthesis.

PS C:\temp> (Invoke-Expression "print.exe /?") | tee-object -filepath test.log
Prints a text file.
 
PRINT [/D:device] [[drive:][path]filename[...]]
 
   /D:device   Specifies a print device.
 
PS C:\temp> get-content test.log
Prints a text file.
 
PRINT [/D:device] [[drive:][path]filename[...]]
 
   /D:device   Specifies a print device.
 
PS C:\temp>

Keep on truckin..

This entry was posted in General and tagged . Bookmark the permalink.

2 Responses to Powershell: Invoke-Expression and Tee-Object

  1. Ryan Gray says:

    More TuneWiz, less PowerShell!

    (Says the guy who hasn’t posted in two months. J/K, keep up the good work!)

  2. Chinh Do says:

    In PS1, if you include the Tee command in your Invoke-Expression expression like below, it’ll work.

    Invoke-Expression “print.exe /?|tee -filepath test.log”
    Invoke-Expression “print.exe /?|tee -variable test”

Leave a Reply

Your email address will not be published. Required fields are marked *