Cara mengarahkan output PowerShell ke file selama eksekusi

198

Saya memiliki skrip PowerShell yang ingin saya redirect output ke file. Masalahnya adalah saya tidak bisa mengubah cara penulisan skrip ini. Jadi saya tidak bisa melakukan:

 .\MyScript.ps1 > output.txt

Bagaimana cara mengarahkan output skrip PowerShell selama eksekusi?

Martin
sumber

Jawaban:

192

Mungkin Start-Transcript akan berhasil untuk Anda. Pertama hentikan jika sudah berjalan, kemudian mulai, dan hentikan setelah selesai.

$ ErrorActionPreference = "SilentlyContinue"
Stop-Transkrip | keluar-nol
$ ErrorActionPreference = "Lanjutkan"
Start-Transcript -path C: \ output.txt -append
# Lakukan beberapa hal
Stop-Transkrip

Anda juga dapat menjalankan ini sambil mengerjakan hal-hal dan menyimpannya sesi sesi perintah Anda untuk referensi nanti.

Jika Anda ingin sepenuhnya menekan kesalahan ketika mencoba menghentikan transkrip yang tidak transkrip, Anda bisa melakukan ini:

$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue" # or "Stop"
Awal
sumber
13
Perhatikan bahwa mulai-transkrip tidak merekam Write-Error, Write-Verbose, atau Write-Debug ... hanya output standar.
Richard Berg
6
@ Richard: tampaknya melakukannya sekarang. Mungkin ini adalah tambahan 2.0, tidak yakin apakah semua jawaban ini berlaku untuk 1.0.
Robert S Ciaccio
Saya menggunakan kode yang hampir sama di atas. masalah saya adalah, Stop-Transkrip | keluar-nol masih mengirimkan output kesalahan jika transkrip tidak dimulai. Saya perlu menekan pesan karena mengacaukan tata letak saya. -perilaku diam-diam melanjutkan tidak membantu juga. ada ide?
Mel
4
Akhirnya, saya menemukan dokumen untuk Mulai-Transkrip . (dengan putus asa tidak diberi label dengan nomor versi Powershell). Ini mengatakan "transkrip termasuk semua perintah yang diketik pengguna dan semua output yang muncul pada konsol". Namun, saya menguji Start-Transkrip di Powershell 2.0, dan menemukan @Richard benar, kesalahan standar tidak disimpan ke transkrip. Ini menyebalkan!
Kolonel Panic
Metode ini tampaknya tidak memperingatkan Anda jika Anda benar-benar memiliki izin untuk menulis ke lokasi yang ditentukan.
demongolem
51

Microsoft telah mengumumkan di situs web Powershell's Connections (2012-02-15 pada 16:40) bahwa dalam versi 3.0 mereka telah memperluas pengalihan sebagai solusi untuk masalah ini.

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

Lihat artikel bantuan "about_Redirection" untuk detail dan contoh.

help about_Redirection
Nathan Hartley
sumber
1
Tidak mengatakan saya suka solusi ini. Bahkan, saya merasa jelek, sulit diingat dan tidak fleksibel. Sepertinya menambahkan parameter stream capture ke Out- *, Set-Content dan Tambah-Konten Cmdlet akan melakukan trik dengan cara yang lebih Powershelly. Sementara mereka melakukannya, mereka juga harus menambahkan parameter -PassThru. Yang secara efektif akan membuat Cmdlet Tee-Object yang kurang berguna menjadi usang.
Nathan Hartley
Saya bingung, bagaimana ini menjawab pertanyaan yang diajukan? "Bagaimana cara mengarahkan output skrip PowerShell selama eksekusi '?
Zoredache
Anda benar, @Zoredache, sepertinya saya mengabaikan persyaratan "tidak dapat mengubah cara penulisan skrip ini". Saat menangkap sebagian besar output, Mulai-Transkrip adalah cara yang harus dilakukan. Haruskah saya menghapus jawaban ini?
Nathan Hartley
1
Bagi mereka yang datang ke sini untuk pengalihan umum, Powershell telah menambahkan -OutVariable -WarningVariable -ErrorVariable, yang langsung menjawab komentar Jan 3 '14 saya.
Nathan Hartley
2
Tidak, tidak apa-apa meninggalkannya. Mengingat jumlah suara yang naik itu jelas berguna. Pertanyaan ini hampir pasti adalah mendapatkan hit Google dari orang-orang yang dapat mengubah cara script dipanggil.
Zoredache
36

Menggunakan:

Write "Stuff to write" | Out-File Outputfile.txt -Append
Fred
sumber
2
tidak menyelesaikan pertanyaan OP karena tidak berfungsi "selama eksekusi". Tapi saya sudah memberi +1 karena berguna untuk mengetahui cara memasang pipa di Powershell.
Paul Masri-Stone
28

Saya kira Anda bisa memodifikasi MyScript.ps1. Kemudian cobalah untuk mengubahnya seperti ini:

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

Saya baru saja mencoba ini dengan PowerShell 3. Anda dapat menggunakan semua opsi pengalihan seperti pada jawaban Nathan Hartley .

mplwork
sumber
Saya suka solusi ini. Anda dapat menggunakan >> output.txt untuk menambahkan. Adakah yang tahu jika ada cara untuk membuat ascii ini alih-alih unicode?
Prof Von Lemongargle
1
Anda mungkin mencoba sesuatu seperti ini: *>&1 | Out-File $log -Encoding ascii -Append -Width 132tetapi Powershell benar-benar jelek jika Anda perlu mengontrol output dengan tepat.
mplwork
Saya lebih suka ini karena berfungsi di dalam skrip Anda. Sempurna untuk gelandangan.
user3505901
25

Salah satu solusi yang mungkin, jika situasi Anda memungkinkan:

  1. Ganti nama MyScript.ps1 menjadi TheRealMyScript.ps1
  2. Buat MyScript.ps1 baru yang terlihat seperti:

    . \ TheRealMyScript.ps1> output.txt

zdan
sumber
18
powershell ".\MyScript.ps1" > test.log
suiwenfeng
sumber
1
Ini adalah satu - satunya dari banyak opsi yang berfungsi untuk output skrip saya.
cori
17

Anda mungkin ingin melihat Tee-Object cmdlet . Anda dapat menyalurkan output ke Tee dan akan menulis ke pipeline dan juga ke file

Andy Schneider
sumber
1
"output" | Set-Content -PassThru dan "output" | Add-Content -PassThru juga akan berfungsi seperti Tee-Object, dengan manfaat tambahan yang bisa Anda atur Encoding.
Nathan Hartley
16

Jika Anda ingin pengalihan langsung semua output ke file, coba gunakan *>>:

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

Karena ini adalah pengalihan langsung ke file, itu tidak akan ditampilkan ke konsol (sering membantu). Jika Anda menginginkan output konsol, gabungkan semua output dengan *&>1, dan kemudian pipa dengan 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 ;

Saya percaya teknik ini didukung di PowerShell 3.0 atau yang lebih baru; Saya menguji pada PowerShell 5.0.

sonjz
sumber
4

Jika Anda ingin melakukannya dari baris perintah dan tidak dibangun ke dalam skrip itu sendiri, gunakan:

.\myscript.ps1 | Out-File c:\output.csv
Chris
sumber
7
Penanya secara eksplisit menjelaskan bahwa panggilan skrip tidak dapat diubah.
Fer
3
Tidak terkait dengan pertanyaan itu, tetapi membantu saya, saya googling untuk mendapatkan Sintaks yang tepat dengan Pipe to Out-File.
gReX
0

Untuk menanamkan ini dalam skrip Anda, Anda dapat melakukannya seperti ini:

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

Itu harus melakukan trik.

bbcompent1
sumber