Cómo redirigir la salida de un PowerShell a un archivo durante su ejecución

198

Tengo un script de PowerShell para el que me gustaría redirigir la salida a un archivo. El problema es que no puedo cambiar la forma en que se llama este script. Entonces no puedo hacer:

 .\MyScript.ps1 > output.txt

¿Cómo redirijo la salida de un script de PowerShell durante su ejecución?

Martín
fuente

Respuestas:

192

Tal vez Start-Transcript funcione para ti. Primero deténgalo si ya está funcionando, luego inícielo y deténgalo cuando haya terminado.

$ ErrorActionPreference = "SilentlyContinue"
Stop-Transcript | nulo
$ ErrorActionPreference = "Continuar"
Start-Transcript -path C: \ output.txt -append
# Haz algunas cosas
Stop-Transcript

También puede hacer que esto se ejecute mientras trabaja en cosas y que guarde sus sesiones de línea de comandos para referencia posterior.

Si desea suprimir por completo el error al intentar detener una transcripción que no se está transcribiendo, puede hacer esto:

$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue" # or "Stop"
Bratch
fuente
13
Tenga en cuenta que start-transcript no registra Write-Error, Write-Verbose o Write-Debug ... solo la salida estándar.
Richard Berg
66
@richard: parece hacerlo ahora. Tal vez esta es una adición 2.0, no estoy seguro si todas estas respuestas se aplican a 1.0.
Robert S Ciaccio
Estoy usando casi el mismo código anterior. mi problema es que Stop-Transcript | out-null todavía envía un mensaje de error si no se inicia la transcripción. Necesito suprimir el mensaje ya que ensucia mi diseño. -la erradicación silenciosa no ayuda tampoco. ¿algunas ideas?
Mel
44
Por fin, encontré los documentos para Start-Transcript . (frustrantemente no etiquetado con el número de versión de Powershell). Se dice que "La transcripción incluye todos los comandos que escribe el usuario y toda la salida que aparece en la consola". Sin embargo, probé Start-Transcript en Powershell 2.0 y descubrí que @Richard tiene razón, el error estándar no se guarda en la transcripción. Esto apesta!
Coronel Panic
Este método no parece advertirle si realmente tiene permiso para escribir en la ubicación especificada.
demongolem
51

Microsoft ha anunciado en el sitio web de Powershell Connections (15/02/2012 a las 4:40 p.m.) que en la versión 3.0 han extendido la redirección como una solución a este problema.

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

Consulte el artículo de ayuda "about_Redirection" para obtener detalles y ejemplos.

help about_Redirection
Nathan Hartley
fuente
1
No digo que me guste esta solución. De hecho, me parece feo, difícil de recordar e inflexible. Parece que agregar parámetros de captura de flujo a los Cmdlets Out- *, Set-Content y Add-Content habría hecho el truco de una manera más Powershelly. Mientras lo hacen, también deben agregar un parámetro -PassThru. Lo que efectivamente haría obsoleto el poco útil Cmdlet Tee-Object.
Nathan Hartley
Estoy confundido, ¿cómo responde esto a la pregunta que se hace? "¿Cómo redirijo la salida de un script de PowerShell durante su ejecución '?
Zoredache
Tiene razón, @Zoredache, parece haber pasado por alto el requisito de "no se puede cambiar la forma en que se llama este script". Al capturar la mayoría de la salida, Start-Transcript es el camino a seguir. ¿Debo eliminar esta respuesta?
Nathan Hartley
1
Para aquellos que vienen aquí para una redirección general, Powershell ha agregado -OutVariable -WarningVariable -ErrorVariable, que responde directamente a mi comentario del 3 de enero de 2014.
Nathan Hartley
2
No, está bien dejarlo. Dado el número de votos positivos, obviamente es útil. Esta pregunta casi con certeza es obtener éxitos de Google de personas que pueden cambiar la forma en que se llama el script.
Zoredache
36

Utilizar:

Write "Stuff to write" | Out-File Outputfile.txt -Append
Fred
fuente
2
no resuelve la pregunta del OP porque no funciona "durante la ejecución". Pero le he dado +1 porque de todos modos es útil saber cómo canalizar Powershell.
Paul Masri-Stone
28

Supongo que puedes modificarlo MyScript.ps1. Luego intenta cambiarlo así:

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

Acabo de probar esto con PowerShell 3. Puede usar todas las opciones de redireccionamiento como en la respuesta de Nathan Hartley .

mplwork
fuente
Me gusta esta solución Puede usar >> output.txt para agregar. ¿Alguien sabe si hay una manera de que esto cree ascii en lugar de unicode?
Prof. Von Lemongargle
1
Puede intentar algo como esto: *>&1 | Out-File $log -Encoding ascii -Append -Width 132pero Powershell es realmente feo si necesita controlar con precisión la salida.
mplwork
Prefiero esto ya que funciona dentro de tu script. Perfecto para vagabundo.
user3505901
25

Una posible solución, si su situación lo permite:

  1. Cambie el nombre de MyScript.ps1 a TheRealMyScript.ps1
  2. Cree un nuevo MyScript.ps1 que se vea así:

    . \ TheRealMyScript.ps1> output.txt

zdan
fuente
18
powershell ".\MyScript.ps1" > test.log
suiwenfeng
fuente
1
Esta fue la única de las muchas opciones que funcionaron para mi salida de script.
cori
17

Es posible que desee echar un vistazo al cmdlet Tee-Object . Puede canalizar la salida a Tee y escribirá en la tubería y también en un archivo

Andy Schneider
fuente
1
"salida" | Set-Content -PassThru y "output" | Add-Content -PassThru también funcionará como Tee-Object, con el beneficio adicional de que puede configurar la codificación.
Nathan Hartley
16

Si desea una redirección directa de todos los resultados a un archivo, intente usar *>>:

# 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 ;

Como se trata de una redirección directa al archivo, no se enviará a la consola (a menudo útil). Si desea la salida de la consola, combine toda la salida con *&>1y luego canalice con 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 ;

Creo que estas técnicas son compatibles con PowerShell 3.0 o posterior; Estoy probando en PowerShell 5.0.

sonjz
fuente
4

Si desea hacerlo desde la línea de comandos y no está integrado en el script, use:

.\myscript.ps1 | Out-File c:\output.csv
Chris
fuente
77
El autor de la pregunta explica explícitamente que la llamada al script no se puede cambiar.
Fer
3
No relacionado con la pregunta, pero útil para mí, estaba buscando en Google la sintaxis correcta con Pipe to Out-File.
gReX
0

Para incrustar esto en su script, puede hacerlo así:

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

Eso debería hacer el truco.

bbcompent1
fuente