Jak przekierować wyjście programu PowerShell do pliku podczas jego wykonywania


198

Mam skrypt PowerShell, dla którego chciałbym przekierować dane wyjściowe do pliku. Problem polega na tym, że nie mogę zmienić sposobu, w jaki ten skrypt jest wywoływany. Więc nie mogę zrobić:

 .\MyScript.ps1 > output.txt

Jak przekierować dane wyjściowe skryptu PowerShell podczas jego wykonywania?

Odpowiedzi:


192

Może Start-Transcriptzadziałałoby dla ciebie. Najpierw zatrzymaj go, jeśli już działa, a następnie uruchom i zatrzymaj po zakończeniu.

$ ErrorActionPreference = "SilentlyContinue"
Zatrzymaj transkrypcję | out-null
$ ErrorActionPreference = "Kontynuuj"
Start-Transcript -path C: \ output.txt -append
# Zrób coś
Zatrzymaj transkrypcję

Możesz także uruchomić to podczas pracy nad rzeczami i zapisać sesje wiersza poleceń do późniejszego wykorzystania.

Jeśli chcesz całkowicie ukryć błąd podczas próby zatrzymania transkrypcji, która nie jest transkrybowana, możesz to zrobić:

$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue" # or "Stop"

13
Zauważ, że transkrypt startowy nie zapisuje błędu zapisu, zapisu pełnego lub zapisu zapisu tylko standardowe wyjście.
Richard Berg

6
@richard: wydaje się, że robi to teraz. Być może jest to dodatek do wersji 2.0, nie jestem pewien, czy wszystkie te odpowiedzi dotyczą wersji 1.0.
Robert S Ciaccio,

Używam prawie tego samego kodu powyżej. moim problemem jest to, że Stop-Transcript | out-null nadal wysyła komunikat o błędzie, jeśli transkrypcja nie została rozpoczęta. Muszę ukryć wiadomość, która zakłóca mój układ. -erroraction silentlycontinue też nie pomaga. jakieś pomysły?
Mel

4
W końcu znalazłem dokumenty do Start-Transcript . (frustrująco nie oznaczone numerem wersji Powershell). To mówi „Zapis zawiera wszystkie polecenia, które użytkownik wpisze a sygnał wyjściowy, który pojawia się na konsoli”. Jednak przetestowałem Start-Transcript w Powershell 2.0 i stwierdziłem, że @Richard ma rację, błąd standardowy nie jest zapisywany w transkrypcji. To jest do bani!
Pułkownik Panic

Ta metoda nie wydaje się ostrzegać, jeśli faktycznie masz uprawnienia do zapisu w określonej lokalizacji.
demongolem

51

Microsoft ogłosił na stronie internetowej Powershell Connections (2012-02-15 o 16:40), że w wersji 3.0 rozszerzyli przekierowanie jako rozwiązanie tego problemu.

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

Szczegółowe informacje i przykłady można znaleźć w artykule pomocy „about_Redirection”.

help about_Redirection

1
Nie mówię, że podoba mi się to rozwiązanie. W rzeczywistości uważam to za brzydkie, trudne do zapamiętania i nieelastyczne. Wydaje się, że dodanie parametrów przechwytywania strumienia do poleceń cmdletów Out- *, Set-Content i Add-Content rozwiązałoby ten problem w bardziej Powershelly. W tym momencie powinni również dodać parametr -PassThru. Co sprawiłoby, że mało przydatny Cmdlet Tee-Object stałby się przestarzały.
Nathan Hartley

Jestem zmieszany, w jaki sposób odpowiada to zadawane pytanie? „Jak przekierować dane wyjściowe skryptu PowerShell podczas jego wykonywania”?
Zoredache

Masz rację, @Zoredache. Wydaje mi się, że przeoczyłem wymóg „nie można zmienić sposobu, w jaki ten skrypt jest nazywany”. Przechwytując większość danych wyjściowych, Start-Transcript jest właściwą drogą. Czy powinienem usunąć tę odpowiedź?
Nathan Hartley,

1
Dla tych, którzy przychodzą tutaj po ogólne przekierowanie, Powershell dodał odtąd -OutVariable -WarningVariable -ErrorVariable, co bezpośrednio odpowiada na mój komentarz z 3 stycznia 14.
Nathan Hartley,

2
Nie, można to zostawić. Biorąc pod uwagę liczbę głosów oddanych, jest to oczywiście przydatne. To pytanie prawie na pewno otrzymuje trafienia Google od osób, które są w stanie zmienić sposób wywoływania skryptu.
Zoredache,

36

Posługiwać się:

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

2
nie rozwiązuje pytania PO, ponieważ nie działa „podczas wykonywania”. Ale dałem mu +1, ponieważ i tak warto wiedzieć, jak tworzyć potoki w Powershell.
Paul Masri-Stone

28

Rozumiem, że możesz to zmodyfikować MyScript.ps1. Następnie spróbuj to zmienić w następujący sposób:

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

Właśnie próbowałem tego z PowerShell 3. Możesz użyć wszystkich opcji przekierowania, jak w odpowiedzi Nathana Hartleya .


Podoba mi się to rozwiązanie. Aby dodać, możesz użyć >> output.txt. Czy ktoś wie, czy istnieje sposób, aby utworzyć to ascii zamiast Unicode?
Prof Von Lemongargle,

1
Możesz spróbować czegoś takiego: *>&1 | Out-File $log -Encoding ascii -Append -Width 132ale PowerShell jest naprawdę brzydki, jeśli chcesz precyzyjnie kontrolować wyjście.
mplwork

Wolę to, ponieważ działa w twoim skrypcie. Idealny dla włóczęgów.
user3505901

25

Jedno możliwe rozwiązanie, jeśli pozwala na to Twoja sytuacja:

  1. Zmień nazwę MyScript.ps1 na TheRealMyScript.ps1
  2. Utwórz nowy MyScript.ps1, który wygląda następująco:

    . \ TheRealMyScript.ps1> output.txt


18
powershell ".\MyScript.ps1" > test.log

1
To była jedyna z wielu opcji, które działały na mój wynik skryptu.
cori

17

Możesz rzucić okiem na obiekt cmdlet Tee-Object . Możesz przesłać dane wyjściowe do Tee, a ono zapisze w potoku, a także w pliku


1
„wyjście” | Set-Content -PassThru i „output” | Add-Content -PassThru będzie również działać jak Tee-Object, z dodatkową korzyścią, że możesz ustawić kodowanie.
Nathan Hartley,

16

Jeśli chcesz prosto przekierować wszystkie dane wyjściowe do pliku, spróbuj użyć *>>:

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

Ponieważ jest to proste przekierowanie do pliku, nie będzie ono wysyłane do konsoli (często pomocne). Jeśli potrzebujesz danych wyjściowych konsoli, połącz wszystkie dane wyjściowe z *&>1, a następnie potokuj z 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 ;

Wierzę, że te techniki są obsługiwane w PowerShell 3.0 lub nowszym; Testuję na PowerShell 5.0.


4

Jeśli chcesz to zrobić z wiersza poleceń i nie wbudować w sam skrypt, użyj:

.\myscript.ps1 | Out-File c:\output.csv

7
Pytający wyraźnie wyjaśnia, że ​​wywołania skryptu nie można zmienić.
Fer

2
Nie związany z pytaniem, ale pomocny dla mnie, szukałem w Google właściwej składni z potokiem do pliku wyjściowego.
gReX

0

Aby osadzić to w skrypcie, możesz to zrobić w następujący sposób:

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

To powinno wystarczyć.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.