ChatGPT解决这个技术问题 Extra ChatGPT

How to redirect the output of a PowerShell to a file during its execution

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?

As @Nathan mentions in his answer, if you are using Powershell 3.0 or above then this should work. Check this: stackoverflow.com/a/2916392/3197387

P
Peter Mortensen

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"

Note that start-transcript does not record Write-Error, Write-Verbose, or Write-Debug...only standard output.
@richard: it appears to do so now. Maybe this is a 2.0 addition, not sure if these answers all apply to 1.0.
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?
At last, I found the docs for Start-Transcript. ( 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!
This method does not appear to warn you if you actually have permission to write to the location specified.
P
Peter Mortensen

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

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.
I am confused, how does this answer the question being asked? "How do I redirect the output of a PowerShell script during its execution'?
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?
For those coming here for general redirection, Powershell has since added -OutVariable -WarningVariable -ErrorVariable , which directly answers my Jan 3 '14 commentary.
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.
P
Peter Mortensen

Use:

Write "Stuff to write" | Out-File Outputfile.txt -Append

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.
this truncates long line outputs and removes information
P
Peter Mortensen

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.


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?
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.
I prefer this as it works within in your script. Perfect for vagrant.
s
suiwenfeng
powershell ".\MyScript.ps1" > test.log

This was the only of the many options that worked for my script output.
z
zdan

One possible solution, if your situation allows it:

Rename MyScript.ps1 to TheRealMyScript.ps1 Create a new MyScript.ps1 that looks like: .\TheRealMyScript.ps1 > output.txt


P
Peter Mortensen

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.


A
Andy Schneider

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


"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.
P
Peter Mortensen

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

The asker is explicitly explaining that the script call can't be changed.
Not related to the question, but helpful for me, I was googling to get the right Syntax with Pipe to Out-File.
P
Peter Mortensen

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.