Как перенаправить вывод PowerShell в файл во время его выполнения

198

У меня есть сценарий PowerShell, для которого я хотел бы перенаправить вывод в файл. Проблема в том, что я не могу изменить способ вызова этого скрипта. Поэтому я не могу сделать:

 .\MyScript.ps1 > output.txt

Как перенаправить вывод скрипта PowerShell во время его выполнения?

Мартин
источник

Ответы:

192

Может быть, Start-Transcriptбудет работать для вас. Сначала остановите его, если он уже запущен, затем запустите его и остановите, когда закончите.

$ ErrorActionPreference = "SilentlyContinue"
Стоп-Транскрипт | из-нуль
$ ErrorActionPreference = "Продолжить"
Start-Transcript -path C: \ output.txt -append
# Сделать что-нибудь
Стоп-Transcript

Вы также можете запустить его во время работы над материалом и сохранить его в сеансах командной строки для дальнейшего использования.

Если вы хотите полностью устранить ошибку при попытке остановить транскрипцию, которая не транскрибирует, вы можете сделать это:

$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue" # or "Stop"
Bratch
источник
13
Обратите внимание, что start-transcript не записывает Write-Error, Write-Verbose или Write-Debug ... только стандартный вывод.
Ричард Берг
6
@ Richard: похоже, делает это сейчас. Может быть, это дополнение 2.0, не уверен, что все эти ответы относятся к 1.0.
Роберт С. Чаччо
Я использую почти такой же код выше. моя проблема в том, что Stop-Transcript | out-null по-прежнему отправляет сообщение об ошибке, если транскрипция не запущена. Мне нужно подавить сообщение, поскольку оно портит мой макет. -рорракция молча продолжается, тоже не помогает. Любые идеи?
Мел
4
Наконец-то я нашел документы для Start-Transcript . (удручающе не помечен номером версии Powershell). Он говорит: «Стенограмма включает в себя все команды, которые вводит пользователь, и все выходные данные, которые появляются на консоли». Однако я протестировал Start-Transcript в Powershell 2.0 и обнаружил, что @Richard прав, стандартная ошибка не сохраняется в стенограмме. Это отстой!
полковник Паник
Этот метод не предупреждает вас, если у вас есть разрешение на запись в указанное место.
демонголем
51

Microsoft объявила на веб-сайте Powershell Connections (2012-02-15 в 16:40), что в версии 3.0 они расширили перенаправление в качестве решения этой проблемы.

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

Обратитесь к справочной статье about_Redirection за подробностями и примерами.

help about_Redirection
Натан Хартли
источник
1
Не говорю, что мне нравится это решение. На самом деле, я нахожу это уродливым, трудно запоминающимся и негибким. Похоже, что добавление параметров захвата потока в командлеты Out- *, Set-Content и Add-Content помогло бы сделать это более мощным способом. Пока они в этом, они также должны добавить параметр -PassThru. Что фактически сделало бы менее чем полезный командлет Tee-Object устаревшим.
Натан Хартли
Я в замешательстве, как это отвечает на задаваемый вопрос? «Как перенаправить вывод скрипта PowerShell во время его выполнения?»
Zoredache
Вы правы, @Zoredache, я, кажется, пропустил требование "не могу изменить способ, которым этот скрипт называется". При захвате большей части выходных данных Start-Transcript - это путь. Должен ли я удалить этот ответ?
Натан Хартли,
1
Для тех, кто пришел сюда для общего перенаправления, Powershell с тех пор добавил -OutVariable -WarningVariable -ErrorVariable, который прямо отвечает на мой комментарий от 3 января 14 года.
Натан Хартли,
2
Нет, это нормально оставить. Учитывая количество голосов за это, очевидно, полезно. Этот вопрос почти наверняка вызывает у пользователей Google отклики, которые могут изменить способ вызова сценария.
Зоредаче
36

Использование:

Write "Stuff to write" | Out-File Outputfile.txt -Append
Фред
источник
2
не решает вопрос ОП, потому что он не работает "во время исполнения". Но я дал ему +1, потому что в любом случае полезно знать, как транслировать в Powershell.
Пол Масри-Стоун
28

Я так понимаю, вы можете изменить MyScript.ps1. Затем попробуйте изменить это так:

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

Я только что попробовал это с PowerShell 3. Вы можете использовать все параметры перенаправления, как в ответе Натана Хартли .

mplwork
источник
Мне нравится это решение. Вы можете использовать >> output.txt для добавления. Кто-нибудь знает, есть ли способ создать это ascii вместо Unicode?
Профессор фон Лемонгаргл
1
Вы можете попробовать что-то вроде этого: *>&1 | Out-File $log -Encoding ascii -Append -Width 132но Powershell действительно безобразен, если вам нужно точно контролировать вывод.
mplwork
Я предпочитаю это, поскольку это работает в вашем сценарии. Идеально подходит для бродяги.
user3505901
25

Одно из возможных решений, если ваша ситуация позволяет это:

  1. Переименуйте MyScript.ps1 в TheRealMyScript.ps1
  2. Создайте новый MyScript.ps1, который выглядит следующим образом:

    . \ TheRealMyScript.ps1> output.txt

Zdan
источник
18
powershell ".\MyScript.ps1" > test.log
suiwenfeng
источник
1
Это был единственный из множества вариантов, которые работали для вывода моего скрипта.
Cori
17

Возможно, вы захотите взглянуть на командлет Tee-Object . Вы можете передать вывод в Tee, и он будет записывать в конвейер, а также в файл

Энди Шнайдер
источник
1
«вывод» | Set-Content -PassThru и «вывод» | Add-Content -PassThru также будет работать как Tee-Object, с дополнительным преимуществом, которое вы можете установить кодировку.
Натан Хартли
16

Если вы хотите прямое перенаправление всего вывода в файл, попробуйте использовать *>>:

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

Поскольку это прямое перенаправление в файл, оно не будет выводиться на консоль (часто полезно). Если вы хотите получить консольный вывод, объедините весь вывод с *&>1, а затем передайте с 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 ;

Я считаю, что эти методы поддерживаются в PowerShell 3.0 или более поздней версии; Я тестирую на PowerShell 5.0.

sonjz
источник
4

Если вы хотите сделать это из командной строки, а не встроить в сам скрипт, используйте:

.\myscript.ps1 | Out-File c:\output.csv
Крис
источник
7
Аскер явно объясняет, что вызов скрипта не может быть изменен.
Фер
3
Не связанный с вопросом, но полезный для меня, я гуглил, чтобы получить правильный синтаксис с Pipe to Out-File.
gReX
0

Чтобы встроить это в ваш скрипт, вы можете сделать это так:

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

Это должно делать свое дело.

bbcompent1
источник