So leiten Sie die Ausgabe einer PowerShell während ihrer Ausführung in eine Datei um

198

Ich habe ein PowerShell-Skript, für das ich die Ausgabe in eine Datei umleiten möchte. Das Problem ist, dass ich die Art und Weise, wie dieses Skript aufgerufen wird, nicht ändern kann. Also kann ich nicht tun:

 .\MyScript.ps1 > output.txt

Wie leite ich die Ausgabe eines PowerShell-Skripts während seiner Ausführung um?

Martin
quelle

Antworten:

192

Vielleicht Start-Transcriptwürde für Sie arbeiten. Stoppen Sie es zuerst, wenn es bereits ausgeführt wird, starten Sie es dann und stoppen Sie es, wenn Sie fertig sind.

$ ErrorActionPreference = "SilentlyContinue"
Stop-Transcript | out-null
$ ErrorActionPreference = "Weiter"
Start-Transcript-Pfad C: \ output.txt -append
# Mach ein paar Sachen
Stop-Transcript

Sie können dies auch ausführen, während Sie an Dingen arbeiten, und Ihre Befehlszeilensitzungen zum späteren Nachschlagen speichern.

Wenn Sie den Fehler vollständig unterdrücken möchten, wenn Sie versuchen, ein Transkript zu stoppen, das nicht transkribiert wird, können Sie Folgendes tun:

$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue" # or "Stop"
Bratch
quelle
13
Beachten Sie, dass das Start-Transkript keine Schreibausgabe, Schreibverbose oder Schreibdebug ... nur die Standardausgabe aufzeichnet.
Richard Berg
6
@richard: es scheint jetzt so zu sein. Vielleicht ist dies eine 2.0-Ergänzung, nicht sicher, ob diese Antworten alle für 1.0 gelten.
Robert S Ciaccio
Ich verwende fast den gleichen Code wie oben. Mein Problem ist, dass Stop-Transcript | out-null immer noch eine Fehlerausgabe sendet, wenn die Transkription nicht gestartet wird. Ich muss die Nachricht unterdrücken, da sie mein Layout durcheinander bringt. - Fehlerhaftes stilles Fortfahren hilft auch nicht. irgendwelche Ideen?
Mel
4
Endlich habe ich die Dokumente für Start-Transcript gefunden . (frustrierend nicht mit Powershell-Versionsnummer gekennzeichnet). Es heißt "Das Transkript enthält alle Befehle, die der Benutzer eingibt, und alle Ausgaben, die auf der Konsole angezeigt werden". Ich habe jedoch Start-Transcript in Powershell 2.0 getestet und festgestellt, dass @Richard richtig ist. Der Standardfehler wird nicht im Transkript gespeichert. Das ist scheiße!
Colonel Panic
Diese Methode scheint Sie nicht zu warnen, wenn Sie tatsächlich die Berechtigung haben, an den angegebenen Speicherort zu schreiben.
Demongolem
51

Microsoft hat auf der Connections-Website von Powershell (15.02.2012, 16:40 Uhr) angekündigt, dass in Version 3.0 die Umleitung als Lösung für dieses Problem erweitert wurde.

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

Weitere Informationen und Beispiele finden Sie im Hilfeartikel "about_Redirection".

help about_Redirection
Nathan Hartley
quelle
1
Ich sage nicht, dass mir diese Lösung gefällt. Tatsächlich finde ich es hässlich, schwer zu merken und unflexibel. Es scheint, als hätte das Hinzufügen von Stream-Capturing-Parametern zu den Cmdlets Out- *, Set-Content und Add-Content den Trick auf eine Powershelly-Art und Weise ausgeführt. Während sie gerade dabei sind, sollten sie auch einen -PassThru-Parameter hinzufügen. Dies würde das weniger nützliche Tee-Object-Cmdlet effektiv überflüssig machen.
Nathan Hartley
Ich bin verwirrt, wie beantwortet dies die gestellte Frage? "Wie
leite
Sie haben Recht, @Zoredache, ich habe anscheinend die Anforderung "Kann die Bezeichnung dieses Skripts nicht ändern" übersehen. Wenn Sie den größten Teil der Ausgabe erfassen, ist Start-Transcript der richtige Weg. Soll ich diese Antwort entfernen?
Nathan Hartley
1
Für diejenigen, die zur allgemeinen Umleitung hierher kommen, hat Powershell seitdem -OutVariable -WarningVariable -ErrorVariable hinzugefügt, das meinen Kommentar vom 3. Januar 14 direkt beantwortet.
Nathan Hartley
2
Nein, es ist in Ordnung, es zu verlassen. Angesichts der Anzahl der Up-Votes ist dies offensichtlich nützlich. Diese Frage führt mit ziemlicher Sicherheit zu Google-Treffern von Personen, die die Art und Weise ändern können, wie das Skript aufgerufen wird.
Zoredache
36

Verwenden:

Write "Stuff to write" | Out-File Outputfile.txt -Append
Fred
quelle
2
löst die Frage des OP nicht, weil es "während der Ausführung" nicht funktioniert. Aber ich habe es +1 gegeben, weil es trotzdem nützlich ist zu wissen, wie man in Powershell pfeift.
Paul Masri-Stone
28

Ich nehme an, Sie können ändern MyScript.ps1. Versuchen Sie dann, es so zu ändern:

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

Ich habe dies gerade mit PowerShell 3 versucht. Sie können alle Umleitungsoptionen wie in Nathan Hartleys Antwort verwenden .

mplwork
quelle
Ich mag diese Lösung. Sie können >> output.txt zum Anhängen verwenden. Weiß jemand, ob es eine Möglichkeit gibt, Ascii anstelle von Unicode zu erstellen?
Prof. Von Lemongargle
1
Sie könnten so etwas versuchen: *>&1 | Out-File $log -Encoding ascii -Append -Width 132Aber Powershell ist wirklich hässlich, wenn Sie die Ausgabe präzise steuern müssen.
Mplwork
Ich bevorzuge dies, da es in Ihrem Skript funktioniert. Perfekt für Landstreicher.
user3505901
25

Eine mögliche Lösung, wenn Ihre Situation dies zulässt:

  1. Benennen Sie MyScript.ps1 in TheRealMyScript.ps1 um
  2. Erstellen Sie eine neue MyScript.ps1, die wie folgt aussieht:

    . \ TheRealMyScript.ps1> output.txt

zdan
quelle
18
powershell ".\MyScript.ps1" > test.log
suiwenfeng
quelle
1
Dies war die einzige der vielen Optionen, die für meine Skriptausgabe funktionierten.
Cori
17

Vielleicht möchten Sie sich das Cmdlet Tee-Object ansehen . Sie können die Ausgabe an Tee weiterleiten und sie wird in die Pipeline und auch in eine Datei geschrieben

Andy Schneider
quelle
1
"Ausgabe" | Set-Content -PassThru und "output" | Add-Content -PassThru funktioniert auch wie Tee-Object, mit dem zusätzlichen Vorteil, dass Sie die Codierung festlegen können.
Nathan Hartley
15

Wenn Sie alle Ausgaben direkt in eine Datei umleiten möchten, versuchen Sie Folgendes *>>:

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

Da dies eine direkte Weiterleitung in eine Datei ist, wird sie nicht an die Konsole ausgegeben (häufig hilfreich). Wenn Sie die Konsolenausgabe wünschen, kombinieren Sie alle Ausgaben mit *&>1und leiten Sie dann mit 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 ;

Ich glaube, diese Techniken werden in PowerShell 3.0 oder höher unterstützt. Ich teste auf PowerShell 5.0.

sonjz
quelle
4

Wenn Sie dies über die Befehlszeile tun möchten und nicht in das Skript selbst integriert sind, verwenden Sie:

.\myscript.ps1 | Out-File c:\output.csv
Chris
quelle
7
Der Fragesteller erklärt ausdrücklich, dass der Skriptaufruf nicht geändert werden kann.
Fer
2
Nicht im Zusammenhang mit der Frage, aber hilfreich für mich, habe ich gegoogelt, um die richtige Syntax mit Pipe to Out-File zu erhalten.
gReX
0

Um dies in Ihr Skript einzubetten, können Sie dies folgendermaßen tun:

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

Das sollte den Trick machen.

bbcompent1
quelle