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?

Jaskółka oknówka
źródło

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"
Bratch
źródło
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
Nathan Hartley
źródło
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
Fred
źródło
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 .

mplwork
źródło
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

zdan
źródło
18
powershell ".\MyScript.ps1" > test.log
suiwenfeng
źródło
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

Andy Schneider
źródło
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.

sonjz
źródło
4

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

.\myscript.ps1 | Out-File c:\output.csv
Chris
źródło
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ć.

bbcompent1
źródło