Comment rediriger la sortie d'un PowerShell vers un fichier lors de son exécution

198

J'ai un script PowerShell pour lequel je voudrais rediriger la sortie vers un fichier. Le problème est que je ne peux pas changer la façon dont ce script est appelé. Je ne peux donc pas faire:

 .\MyScript.ps1 > output.txt

Comment rediriger la sortie d'un script PowerShell lors de son exécution?

Martin
la source

Réponses:

192

Peut être Start-Transcript - que ça marcherait pour vous. Arrêtez-le d'abord s'il est déjà en cours d'exécution, puis démarrez-le et arrêtez-le lorsque vous avez terminé.

$ ErrorActionPreference = "SilentlyContinue"
Stop-Transcript | out-null
$ ErrorActionPreference = "Continuer"
Start-Transcript -path C: \ output.txt -append
# Faites des trucs
Stop-Transcript

Vous pouvez également l'exécuter tout en travaillant sur des choses et le faire enregistrer vos sessions de ligne de commande pour référence ultérieure.

Si vous souhaitez supprimer complètement l'erreur lorsque vous tentez d'arrêter une transcription qui n'est pas en cours de transcription, vous pouvez procéder comme suit:

$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue" # or "Stop"
Bratch
la source
13
Notez que start-transcript n'enregistre pas Write-Error, Write-Verbose ou Write-Debug ... uniquement la sortie standard.
Richard Berg
6
@richard: il semble le faire maintenant. Il s'agit peut-être d'un ajout 2.0, je ne sais pas si ces réponses s'appliquent toutes à 1.0.
Robert S Ciaccio
J'utilise presque le même code ci-dessus. mon problème est que Stop-Transcript | out-null envoie toujours une sortie d'erreur si la transcription n'est pas démarrée. J'ai besoin de supprimer le message car il gâche ma disposition. -erroraction silencieusementcontinuer n'aide pas non plus. des idées?
Mel
4
Enfin, j'ai trouvé les documents pour Start-Transcript . (malheureusement pas étiqueté avec le numéro de version de Powershell). Il dit "La transcription comprend toutes les commandes que l'utilisateur tape et toutes les sorties qui apparaissent sur la console". Cependant, j'ai testé Start-Transcript dans Powershell 2.0 et j'ai trouvé que @Richard avait raison, l'erreur standard n'est pas enregistrée dans la transcription. Ça craint!
Colonel Panic
Cette méthode ne semble pas vous avertir si vous avez réellement l'autorisation d'écrire à l'emplacement spécifié.
demongolem
51

Microsoft a annoncé sur le site Web de Powershell Connections (15/02/2012 à 16h40) que dans la version 3.0, ils ont étendu la redirection comme solution à ce problème.

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

Consultez l'article d'aide "about_Redirection" pour plus de détails et des exemples.

help about_Redirection
Nathan Hartley
la source
1
Je ne dis pas que j'aime cette solution. En fait, je la trouve moche, difficile à retenir et inflexible. On dirait que l'ajout de paramètres de capture de flux aux applets de commande Out- *, Set-Content et Add-Content aurait fait l'affaire d'une manière plus Powershelly. Pendant qu'ils y sont, ils doivent également ajouter un paramètre -PassThru. Ce qui rendrait la cmdlet Tee-Object moins utile obsolète.
Nathan Hartley
Je suis confus, comment cela répond-il à la question posée? "Comment rediriger la sortie d'un script PowerShell pendant son exécution"?
Zoredache
Vous avez raison, @Zoredache, il me semble avoir ignoré l'exigence "ne peut pas changer la façon dont ce script est appelé". Lors de la capture de la majorité de la sortie, Start-Transcript est la voie à suivre. Dois-je supprimer cette réponse?
Nathan Hartley
1
Pour ceux qui viennent ici pour une redirection générale, Powershell a depuis ajouté -OutVariable -WarningVariable -ErrorVariable, qui répond directement à mon commentaire du 3 janvier 2014.
Nathan Hartley
2
Non, c'est bien de le laisser. Étant donné le nombre de votes positifs, cela est évidemment utile. Cette question reçoit presque certainement des hits Google de personnes capables de changer la façon dont le script est appelé.
Zoredache
36

Utilisation:

Write "Stuff to write" | Out-File Outputfile.txt -Append
Fred
la source
2
ne résout pas la question du PO car il ne fonctionne pas "pendant l'exécution". Mais je lui ai donné +1, car il est utile de savoir comment canaliser dans Powershell de toute façon.
Paul Masri-Stone
28

Je suppose que vous pouvez modifier MyScript.ps1. Ensuite, essayez de le changer comme suit:

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

Je viens d'essayer cela avec PowerShell 3. Vous pouvez utiliser toutes les options de redirection comme dans la réponse de Nathan Hartley .

mplwork
la source
J'aime cette solution. Vous pouvez utiliser >> output.txt pour ajouter. Quelqu'un sait-il s'il existe un moyen de créer ce ascii au lieu d'unicode?
Prof Von Lemongargle
1
Vous pourriez essayer quelque chose comme ça: *>&1 | Out-File $log -Encoding ascii -Append -Width 132mais Powershell est vraiment moche si vous avez besoin de contrôler précisément la sortie.
mplwork
Je préfère cela car cela fonctionne dans votre script. Parfait pour vagabond.
user3505901
25

Une solution possible, si votre situation le permet:

  1. Renommez MyScript.ps1 en TheRealMyScript.ps1
  2. Créez un nouveau MyScript.ps1 qui ressemble à:

    . \ TheRealMyScript.ps1> output.txt

zdan
la source
18
powershell ".\MyScript.ps1" > test.log
suiwenfeng
la source
1
C'était la seule des nombreuses options qui fonctionnaient pour la sortie de mon script.
cori
17

Vous voudrez peut-être jeter un œil à la cmdlet Tee-Object . Vous pouvez diriger la sortie vers Tee et elle écrira dans le pipeline et également dans un fichier

Andy Schneider
la source
1
"sortie" | Set-Content -PassThru et "sortie" | Add-Content -PassThru fonctionnera également comme Tee-Object, avec l'avantage supplémentaire que vous pouvez définir l'encodage.
Nathan Hartley
16

Si vous souhaitez une redirection directe de toutes les sorties vers un fichier, essayez d'utiliser *>>:

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

Comme il s'agit d'une redirection directe vers un fichier, elle ne sera pas envoyée à la console (souvent utile). Si vous désirez la sortie de la console, combinez toutes les sorties avec *&>1, puis canalisez avec 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 ;

Je crois que ces techniques sont prises en charge dans PowerShell 3.0 ou version ultérieure; Je teste sur PowerShell 5.0.

sonjz
la source
4

Si vous souhaitez le faire à partir de la ligne de commande et non intégré au script lui-même, utilisez:

.\myscript.ps1 | Out-File c:\output.csv
Chris
la source
7
Le demandeur explique explicitement que l'appel de script ne peut pas être modifié.
Fer
3
Pas lié à la question, mais utile pour moi, je cherchais sur Google pour obtenir la bonne syntaxe avec Pipe to Out-File.
gReX
0

Pour intégrer cela dans votre script, vous pouvez le faire comme ceci:

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

Cela devrait faire l'affaire.

bbcompent1
la source