262

I have a PowerShell script for which I would like to redirect the output to a file. The problem is that I cannot change the way this script is called. So I cannot do:

 .\MyScript.ps1 > output.txt

How do I redirect the output of a PowerShell script during its execution?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Martin
  • 39,309
  • 62
  • 192
  • 278
  • As @Nathan mentions in his answer, if you are using Powershell 3.0 or above then this should work. Check this: https://stackoverflow.com/a/2916392/3197387 – Sisir Jul 10 '20 at 16:27

10 Answers10

245

Maybe Start-Transcript would work for you. First stop it if it's already running, then start it, and stop it when done.

$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue"
Start-Transcript -path C:\output.txt -append
# Do some stuff
Stop-Transcript

You can also have this running while working on stuff and have it saving your command line sessions for later reference.

If you want to completely suppress the error when attempting to stop a transcript that is not transcribing, you could do this:

$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue" # or "Stop"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bratch
  • 4,103
  • 5
  • 27
  • 32
  • 15
    Note that start-transcript does not record Write-Error, Write-Verbose, or Write-Debug...only standard output. – Richard Berg Aug 01 '09 at 17:25
  • 7
    @richard: it appears to do so now. Maybe this is a 2.0 addition, not sure if these answers all apply to 1.0. – Robert S Ciaccio Dec 15 '10 at 20:43
  • I'm using almost the same code above. my problem is, Stop-Transcript |out-null still sends error output if transcripting is not started. I need to supress the message as it messes out my layout. -erroraction silentlycontinue doesn't help either. any ideas? – Mel Dec 14 '11 at 07:06
  • 4
    At last, I found the docs for [Start-Transcript](http://technet.microsoft.com/en-us/library/hh849687.aspx). ( frustratingly not labelled with Powershell version number). It _says_ "The transcript includes all command that the user types and all output that appears on the console". However, I tested Start-Transcript in Powershell 2.0, and found @Richard is right, standard error _isn't_ saved to the transcript. This sucks! – Colonel Panic Jul 05 '12 at 13:09
  • This method does not appear to warn you if you actually have permission to write to the location specified. – demongolem Sep 14 '16 at 14:53
  • 1
    I try to never mess with the $ErrorActionPreference variable. Too many unintended consequences. As a workaround, you can capture the errant exception and do nothing with it. Which would look like this... try { Stop-Transcript } catch {} – Nathan Hartley Sep 28 '18 at 12:51
  • Random question, but if I were to open this `txt` file while it's being logged to, what happens? I guess it can no longer be logged to and I lose logs until I close the file? – stevec Jul 11 '19 at 00:51
66

Microsoft has announced on Powershell's Connections web site (2012-02-15 at 4:40 PM) that in version 3.0 they have extended the redirection as a solution to this problem.

In PowerShell 3.0, we've extended output redirection to include the following streams: 
 Pipeline (1) 
 Error    (2) 
 Warning  (3) 
 Verbose  (4) 
 Debug    (5)
 All      (*)

We still use the same operators
 >    Redirect to a file and replace contents
 >>   Redirect to a file and append to existing content
 >&1  Merge with pipeline output

See the "about_Redirection" help article for details and examples.

help about_Redirection
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nathan Hartley
  • 4,005
  • 2
  • 43
  • 46
  • 1
    Not saying I like this solution. In fact, I find it ugly, hard to remember and inflexible. Seems like adding stream capturing parameters to the Out-*, Set-Content and Add-Content Cmdlets would have done the trick in a more Powershelly fashion. While they are at it, they should also add a -PassThru parameter. Which would effectively make the less than useful Tee-Object Cmdlet obsolete. – Nathan Hartley Jan 03 '14 at 16:31
  • I am confused, how does this answer the question being asked? "How do I redirect the output of a PowerShell script **during** its execution'? – Zoredache Sep 14 '16 at 22:47
  • You are right, @Zoredache, I seem to have overlooked the "cannot change the way this script is called" requirement. When capturing the majority of the output, Start-Transcript is the way to go. Should I remove this answer? – Nathan Hartley Sep 16 '16 at 20:37
  • 1
    For those coming here for general redirection, Powershell has since added -OutVariable -WarningVariable -ErrorVariable , which directly answers my Jan 3 '14 commentary. – Nathan Hartley Sep 16 '16 at 20:37
  • 2
    No, it is fine to leave it. Given the number of up-votes it is obviously useful. This question almost certainly is getting Google hits from people that are able to change the way the script is being called. – Zoredache Sep 16 '16 at 20:47
  • Didn't understand this answer. The question was about redirection from the script itself. So it implies that we do in the script smth like this? `if ($run_not_from_the_script) { & $myScript *>&1 | tee -File outfile.txt ; return }` – Artyom May 28 '18 at 10:02
59

Use:

Write "Stuff to write" | Out-File Outputfile.txt -Append
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fred
  • 623
  • 5
  • 2
  • 5
    doesn't solve the OP's question because it doesn't work "during execution". But I've given it +1 because it's useful to know how to pipe in Powershell anyway. – Paul Masri-Stone May 11 '17 at 14:07
  • this truncates long line outputs and removes information – AmazingMiki May 30 '21 at 14:15
  • It does work "during execution" The problem is that it is only for that line, and not the entire script. The transcript commands above should work as intended. – Robert Cotterman Nov 02 '22 at 18:55
46

I take it you can modify MyScript.ps1. Then try to change it like so:

$(
    Here is your current script
) *>&1 > output.txt

I just tried this with PowerShell 3. You can use all the redirect options as in Nathan Hartley's answer.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mplwork
  • 1,120
  • 10
  • 21
  • I like this solution. You can use >> output.txt to append. Anyone know if there is a way to have this create ascii instead of unicode? – Prof Von Lemongargle Oct 10 '16 at 22:00
  • 2
    You might try something like this: `*>&1 | Out-File $log -Encoding ascii -Append -Width 132` but Powershell is really ugly if you need to precisely control the output. – mplwork Oct 12 '16 at 13:03
  • I prefer this as it works within in your script. Perfect for vagrant. – user3505901 May 14 '18 at 16:11
33
powershell ".\MyScript.ps1" > test.log
suiwenfeng
  • 1,865
  • 1
  • 25
  • 32
28

If you want a straight redirect of all output to a file, try using *>>:

# You'll receive standard output for the first command, and an error from the second command.
mkdir c:\temp -force *>> c:\my.log ;
mkdir c:\temp *>> c:\my.log ;

Since this is a straight redirect to file, it won't output to the console (often helpful). If you desire the console output, combined all output with *&>1, and then pipe with Tee-Object:

mkdir c:\temp -force *>&1 | Tee-Object -Append -FilePath c:\my.log ;
mkdir c:\temp *>&1 | Tee-Object -Append -FilePath c:\my.log ;

# Shorter aliased version
mkdir c:\temp *>&1 | tee -Append c:\my.log ;

I believe these techniques are supported in PowerShell 3.0 or later; I'm testing on PowerShell 5.0.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sonjz
  • 4,870
  • 3
  • 42
  • 60
  • 1
    I'm not familiar with Powershell, but in the normal CMD you need to add `2>&1` to also redirect STDERR, not just STDOUT. Wouldn't that be the same in Powershell? – antred Sep 08 '22 at 10:06
27

One possible solution, if your situation allows it:

  1. Rename MyScript.ps1 to TheRealMyScript.ps1
  2. Create a new MyScript.ps1 that looks like:

    .\TheRealMyScript.ps1 > output.txt

zdan
  • 28,667
  • 7
  • 60
  • 71
17

You might want to take a look at the cmdlet Tee-Object. You can pipe output to Tee and it will write to the pipeline and also to a file

Andy Schneider
  • 8,516
  • 6
  • 36
  • 52
  • 2
    "output" | Set-Content -PassThru and "output" | Add-Content -PassThru will also work like Tee-Object, with the added benefit that you can set the Encoding. – Nathan Hartley Jul 29 '11 at 16:34
10

If you want to do it from the command line and not built into the script itself, use:

.\myscript.ps1 | Out-File c:\output.csv
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris
  • 143
  • 1
  • 2
  • 8
    The asker is explicitly explaining that the script call can't be changed. – Fer Oct 15 '14 at 09:13
  • 6
    Not related to the question, but helpful for me, I was googling to get the right Syntax with Pipe to Out-File. – gReX Feb 23 '17 at 09:23
0

To embed this in your script, you can do it like this:

        Write-Output $server.name | Out-File '(Your Path)\Servers.txt' -Append

That should do the trick.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bbcompent1
  • 494
  • 1
  • 10
  • 25