Powershell перенаправить вывод ошибок в файл

Аналоги > и >> в PowerShell

Если вы знакомы с операторами командной строки Linux, то вы можете знать, что оператор «>» перенаправляет вывод в файл, если файл существует, то он перезаписывается, если файл не существует, то он создаётся и в него записывается содержимое.

В PowerShell этот оператор также работает, например, в следующей команде результат работы командлета будет сохранён в файл man.txt:

Get-Help about_Comparison_Operators -Full > man.txt

В Linux существует ещё один оператор для перенаправления стандартного вывода, это «>>», который работает аналогично предыдущему, но если файл уже существует, то вместо перезаписи, новые данные дописываются в файл, например, следующая команда допишет выводом командлета содержимое файла man.txt, а если его нет, то создаст этот файл:

Get-Help about_Comparison_Operators -Full >> man.txt

В PowerShell вы можете использовать «>» и «>>» если вам достаточно простого перенаправления вывода в файл. Также имеется командлет Out-File который кроме выполнения перенаправления вывода имеет дополнительную функциональность.

Перенаправление вывода в PowerShell

По умолчанию PowerShell отправляет выходные данные своей команды в консоль PowerShell. Однако вы можете направить вывод в текстовый файл, и вы можете перенаправить вывод ошибок в обычный поток вывода.

Для перенаправления вывода можно использовать следующие методы:

  • Использовать командлет Out-File, который отправляет выходные данные команды в текстовый файл. Как правило, вы используете командлет Out-File когда вам нужно использовать его параметры, такие как параметры -Encoding, -Force, -Width или -NoClobber.
  • Использовать командлет Tee-Object, который отправляет вывод команды в текстовый файл, а затем отправляет его в конвейер.
  • Использовать операторы перенаправления PowerShell.

Операторы перенаправления PowerShell

Операторы перенаправления позволяют отправлять потоки данных в файл или выходной поток SUCCESS.

Операторы перенаправления PowerShell используют следующие числа для представления доступных выходных потоков:

№ потока Описание Представлен в
1 SUCCESS Stream PowerShell 2.0
2 ERROR Stream PowerShell 2.0
3 WARNING Stream PowerShell 3.0
4 VERBOSE Stream PowerShell 3.0
5 DEBUG Stream PowerShell 3.0
6 INFORMATION Stream  PowerShell 5.0
* All Streams PowerShell 3.0

[!ПРИМЕЧАНИЕ] В PowerShell также есть поток PROGRESS, но он не используется для перенаправления.

Ниже перечислены операторы перенаправления PowerShell, где n представляет номер потока. Поток SUCCESS (1) используется по умолчанию, если поток не указан.

Оператор Описание Синтаксис
> Отправить указанный поток в файл. n>
>> ДОБАВИТЬ указанный поток к файлу. n>>
>&1 _Перенаправляет_ указанный поток в поток SUCCESS. n>&1

[!ПРИМЕЧАНИЕ] В отличие от некоторых оболочек Unix, вы можете перенаправлять другие потоки только в поток SUCCESS.

Примеры:

Пример 1: Перенаправление ошибок и вывод в файл

dir 'C:', 'fakepath' 2>&1 > .dir.log

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

Он использует «2>&1» для перенаправления потока ERROR в поток SUCCESS и «>» для отправки результирующего потока SUCCESS в файл с именем dir.log.

Пример 2: Отправить все данные потока SUCCESS в файл

.script.ps1 > script.log

Эта команда отправляет все данные потока SUCCESS в файл с именем script.log.

Пример 3. Отправка потоков Success, Warning и Error в файл

&{
	Write-Warning "hello"
	Write-Error "hello"
	Write-Output "hi"
} 3>&1 2>&1 > P:Tempredirection.log

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

  • 3>&1 перенаправляет поток WARNING в поток SUCCESS.
  • 2>&1 перенаправляет поток ERROR в поток SUCCESS (который теперь также включает все данные потока WARNING)
  • > перенаправляет поток SUCCESS (который теперь содержит потоки WARNING и ERROR) в файл с именем C:tempredirection.log)

Пример 4: Перенаправить все потоки в файл

.script.ps1 *> script.log

В этом примере все потоки выводятся из сценария с именем script.ps1 в файл с именем script.log.

Пример 5: Подавить все данные Write-Host и Information Stream

&{
	Write-Host "Hello"
	Write-Information "Hello" -InformationAction Continue
} 6> $null

В этом примере подавляются все данные Information Stream (информационного потока). Дополнительные сведения о командлетах потока INFORMATION смотрите разделах Write-Host и Write-Information.

Смотрите также: Аналог echo в PowerShell

Примечания:

1. Операторы перенаправления, которые не добавляют данные (> и n>), перезаписывают текущее содержимое указанного файла без предупреждения.

2. Однако, если файл доступен только для чтения, является скрытым или системным файлом, перенаправление ТЕРПИТ НЕУДАЧУ. Операторы перенаправления добавления (>> и n>>) не записывают в файл, доступный только для чтения, но они добавляют содержимое в системный или скрытый файл.

3. Чтобы принудительно перенаправить содержимое в доступный только для чтения, скрытый или системный файл, используйте командлет Out-File с его параметром -Force.

4. Когда вы пишете в файлы, операторы перенаправления используют кодировку Unicode. Если файл имеет другую кодировку, выходные данные могут быть отформатированы неправильно. Чтобы перенаправить содержимое в файлы, отличные от Unicode, используйте командлет Out-File с его параметром -Encoding.

5. Возможная путаница с операторами сравнения

Оператор «>» не следует путать с оператором сравнения Больше (часто обозначается как «>» в других языках программирования).

В зависимости от сравниваемых объектов вывод с использованием «>» может показаться правильным (поскольку 36 не больше 42).

if (36 > 42) { "true" } else { "false" }
false

Однако проверка локальной файловой системы позволяет увидеть, что был создан файл с именем 42, а в него записано содержимое 36.

dir

    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    ------          1/02/20  10:10 am              3 42

    cat 42
    36

Попытка использовать обратное сравнение «<» (меньше чем) приводит к системной ошибке:

if (36 < 42) { "true" } else { "false" }
    At line:1 char:8
    + if (36 < 42) { "true" } else { "false" }
    +        ~
    The '<' operator is reserved for future use.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : RedirectionNotSupported

Если требуется числовое сравнение, следует использовать -lt и -gt.

Смотрите также: Операторы сравнения в PowerShell

Как в PowerShell дописать вывод в файл

Итак, оператор «>» перенаправляет вывод, который в противном случае попал бы на экран, в файл. Этот оператор полностью переписывает файл, если он уже существует.

Для того, чтобы вместо замены содержимого файла дописать в него, можно использовать оператор «>>»:

Get-Help about_Comparison_Operators -Full >> man.txt

Командлет Out-File для сохранение в файл в PowerShell

Командлет Out-File отправляет вывод в файл. Когда вам нужно указать параметры для вывода, используйте Out-File вместо оператора перенаправления («>»).

Как дописать файл. Аналог «>>» в Out-File

Для того, чтобы добавить вывод в конец существующего файла (вместо его перезаписи), используйте в вашей команде опцию -Append.

Как указать кодировку

Для изменения кодировки по умолчанию, используйте опцию «-Encoding КОДИРОВКА». Кодировкой по умолчанию является UTF8NoBOM.

Опция -Encoding задаёт тип кодировки для целевого файла. Значение по умолчанию — UTF8NoBOM. Кодировка — это динамический параметр, который поставщик FileSystem добавляет в Set-Content. Этот параметр работает только на дисках с файловой системой. Допустимые значения этого параметра следующие:

  • ASCII: использует кодировку для набора символов ASCII (7-бит).
  • BigEndianUnicode: кодирует в формате UTF-16, используя порядок байтов с прямым порядком байтов.
  • OEM: использует кодировку по умолчанию для MS-DOS и консольных программ.
  • Unicode: кодируется в формате UTF-16 с использованием порядка байтов с прямым порядком байтов.
  • UTF7: кодирует в формате UTF-7.
  • UTF8: кодирует в формате UTF-8.
  • UTF8BOM: кодирует в формате UTF-8 с меткой порядка байтов (BOM)
  • UTF8NoBOM: кодирует в формате UTF-8 без метки порядка байтов (BOM)
  • UTF32: кодирует в формате UTF-32.

Начиная с PowerShell 6.2, параметр -Encoding также позволяет использовать числовые идентификаторы зарегистрированных кодовых страниц (например, «-Encoding 1251») или строковые имена зарегистрированных кодовых страниц (например, «-Encoding «windows-1251»».

Как указать путь до файла

Обязательным аргументом командлета Out-File является путь до файла в который будет сделано сохранение выводимых данных. Вы можете указать его с опцией -FilePath, либо опустить эту опцию и указать путь до файла без неё.

Обратите внимание, что вы не можете использовать подстановочные знаки в пути до файла.

Смотрите также: Подстановочные символы в PowerShell

Как переписать файл только для чтения

С помощью опции -Force вы можете переопределить атрибут только для чтения и перезаписать существующий файл, доступный только для чтения. Параметр -Force не отменяет ограничения безопасности, то есть если у вас нет прав на записи в указываемый файл, то вы всё равно не сможете записать в него..

Как не добавлять символ новой строки (newline) в конец файла

При записи в файл, в конец будет добавлен символ перехода на новую строку. То есть если в файл будут добавлены другие данные, то они будут записаны с новой строки. Если вы не хотите, чтобы добавлялся символ новой строки, то используйте опцию -NoNewline. Если для формирования вывода используется несколько строк, то по умолчанию они разделяются пробелом, эта опция также отменяет вставку пробелов между строк.

Как запретить перезаписывать существующий файл

Опция -NoClobber предотвращает перезапись существующего файла и отображает сообщение о том, что файл уже существует. По умолчанию, если файл существует по указанному пути, Out-File перезаписывает файл без предупреждения.

Что может быть вводом командлета Out-File

В Out-File вы можете отправить по конвейеру любые объекты, а не только строки (как например в Set-Content и Add-Content). Например, следующая команда сохраняет практически пустой файл:

Get-ComputerInfo | Set-Content test3.txt

Но с помощью Out-File весь вывод будет сохранён в файл:

Get-ComputerInfo | Out-File test4.txt

Командлеты типа Out- не форматируют объекты; они просто визуализируют их и отправляют в указанное место отображения. Если вы отправляете неформатированный объект командлету Out-, этот командлет отправляет его командлету форматирования перед его визуализацией.

Чтобы отправить вывод команды PowerShell командлету Out-File, используйте конвейер. Вы можете хранить данные в переменной и использовать параметр -InputObject для передачи данных в командлет Out-File.

Out-File отправляет данные, но не создаёт никаких объектов вывода. Если вы направите вывод Out-File в Get-Member, командлет Get-Member сообщает, что объекты не были указаны.

Пример 1: Отправить вывод и создать файл

Get-Process | Out-File -FilePath .Process.txt
Get-Content -Path .Process.txt
    
    NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
     ------    -----      -----     ------      --  -- -----------
         29    22.39      35.40      10.98   42764   9 Application
         53    99.04     113.96       0.00   32664   0 CcmExec
         27    96.62     112.43     113.00   17720   9 Code

Командлет Get-Process получает список процессов, запущенных на локальном компьютере. Объекты Process отправляются по конвейеру в командлет Out-File. Затем Out-File использует параметр -FilePath и создаёт файл с именем Process.txt в текущем каталоге. Команда Get-Content получает содержимое из файла и отображает его в консоли PowerShell.

Пример 2: Предотвратить перезапись существующего файла

Get-Process | Out-File -FilePath .Process.txt -NoClobber
    
    Out-File : The file 'C:TestProcess.txt' already exists.
    At line:1 char:15
    + Get-Process | Out-File -FilePath .Process.txt -NoClobber
    +               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Командлет Get-Process получает список процессов, запущенных на локальном компьютере. Объекты Process отправляются по конвейеру в командлет Out-File. Затем Out-File использует параметр -FilePath и пытается выполнить запись в файл в текущем каталоге с именем Process.txt. Параметр -NoClobber предотвращает перезапись файла и отображает сообщение о том, что файл уже существует.

Пример 3: Сохранение вывода в файл в кодировке ASCII

$Procs = Get-Process
Out-File -FilePath .Process.txt -InputObject $Procs -Encoding ASCII -Width 50

Командлет Get-Process получает список процессов, запущенных на локальном компьютере. Объекты процесса хранятся в переменной $Procs. Затем Out-File использует параметр -FilePath и создаёт файл с именем Process.txt в текущем каталоге. Параметр -InputObject передаёт объекты с процессами из $Procs в файл Process.txt. Параметр -Encoding преобразует вывод в формат ASCII. Параметр -Width ограничивает каждую строку в файле 50 символами, поэтому некоторые данные могут быть усечены.

Пример 4: Использование провайдера и отправка вывода в файл

Set-Location -Path Alias:
    
Get-Location
    
    Path
    ----
    Alias:
    
Get-ChildItem | Out-File -FilePath C:TestDirAliasNames.txt
    
Get-Content -Path C:TestDirAliasNames.txt
    
    CommandType     Name
    -----------     ----
    Alias           % -> ForEach-Object
    Alias           ? -> Where-Object
    Alias           ac -> Add-Content
    Alias           cat -> Get-Content

Команда Set-Location использует параметр -Path для установки текущего местоположения провайдера реестра «Alias:». Командлет Get-Location отображает полный путь к «Alias:». Get-ChildItem отправляет объекты по конвейеру командлету Out-File. Out-File использует параметр -FilePath, чтобы указать полный путь и имя файла для вывода, C:TestDirAliasNames.txt. Командлет Get-Content использует параметр -Path и отображает содержимое файла в консоли PowerShell.

Связанные статьи:

  • Решение проблем с кодировкой вывода в PowerShell и сторонних утилитах, запущенных в PowerShell (100%)
  • Ошибки «Оператор «<» зарезервирован для использования в будущем» и «The ‘<‘ operator is reserved for future use.» (РЕШЕНО) (100%)
  • Аналог echo в PowerShell (56%)
  • Как в PowerShell менять набор выводимых по умолчанию данных (56%)
  • Как выводить данные без таблицы в PowerShell (56%)
  • Командлеты Set-Content и Add-Content для обработки строк (RANDOM — 50%)
description Locale ms.date online version schema title

Explains how to redirect output from PowerShell to text files.

en-US

05/04/2021

https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_redirection?view=powershell-7.2&WT.mc_id=ps-gethelp

2.0.0

about Redirection

Short description

Explains how to redirect output from PowerShell to text files.

Long description

By default, PowerShell sends output to the PowerShell host. Usually this is the
console application. However, you can redirect the output to a text file and you
can redirect error output to the regular output stream.

You can use the following methods to redirect output:

  • Use the Out-File cmdlet, which sends command output to a text file.
    Typically, you use the Out-File cmdlet when you need to use its parameters,
    such as the Encoding, Force, Width, or NoClobber parameters.

  • Use the Tee-Object cmdlet, which sends command output to a text file and
    then sends it to the pipeline.

  • Use the PowerShell redirection operators. Using the redirection operator with
    a file target is functionally equivalent to piping to Out-File with no
    extra parameters.

For more information about streams, see
about_Output_Streams.

Redirectable output streams

PowerShell supports redirection of the following output streams.

Stream # Description Introduced in Write Cmdlet
1 Success Stream PowerShell 2.0 Write-Output
2 Error Stream PowerShell 2.0 Write-Error
3 Warning Stream PowerShell 3.0 Write-Warning
4 Verbose Stream PowerShell 3.0 Write-Verbose
5 Debug Stream PowerShell 3.0 Write-Debug
6 Information Stream PowerShell 5.0 Write-Information, Write-Host
* All Streams PowerShell 3.0

There is also a Progress stream in PowerShell, but it does not support
redirection.

[!IMPORTANT]
The Success and Error streams are similar to the stdout and stderr
streams of other shells. However, stdin is not connected to the PowerShell
pipeline for input.

PowerShell redirection operators

The PowerShell redirection operators are as follows, where n represents
the stream number. The Success stream ( 1 ) is the default if no stream
is specified.

Operator Description Syntax
> Send specified stream to a file. n>
>> Append specified stream to a file. n>>
>&1 Redirects the specified stream to the Success stream. n>&1

[!NOTE]
Unlike some Unix shells, you can only redirect other streams to the
Success stream.

Examples

Example 1: Redirect errors and output to a file

This example runs dir on one item that will succeed, and one that will error.

dir 'C:', 'fakepath' 2>&1 > .dir.log

It uses 2>&1 to redirect the Error stream to the Success stream, and
> to send the resultant Success stream to a file called dir.log

Example 2: Send all Success stream data to a file

This example sends all Success stream data to a file called script.log.

.script.ps1 > script.log

Example 3: Send Success, Warning, and Error streams to a file

This example shows how you can combine redirection operators to achieve a
desired result.

&{
   Write-Warning "hello"
   Write-Error "hello"
   Write-Output "hi"
} 3>&1 2>&1 > C:Tempredirection.log
  • 3>&1 redirects the Warning stream to the Success stream.
  • 2>&1 redirects the Error stream to the Success stream (which also
    now includes all Warning stream data)
  • > redirects the Success stream (which now contains both Warning
    and Error streams) to a file called C:tempredirection.log)

Example 4: Redirect all streams to a file

This example sends all streams output from a script called script.ps1 to a
file called script.log

.script.ps1 *> script.log

Example 5: Suppress all Write-Host and Information stream data

This example suppresses all information stream data. To read more about
Information stream cmdlets, see
Write-Host and
Write-Information

&{
   Write-Host "Hello"
   Write-Information "Hello" -InformationAction Continue
} 6> $null

Example 6: Show the effect of Action Preferences

Action Preference variables and parameters can change what gets written to a
particular stream. The script in this example shows how the value of
$ErrorActionPreference affects what gets written to the Error stream.

$ErrorActionPreference = 'Continue'
$ErrorActionPreference > log.txt
get-item /not-here 2>&1 >> log.txt

$ErrorActionPreference = 'SilentlyContinue'
$ErrorActionPreference >> log.txt
get-item /not-here 2>&1 >> log.txt

$ErrorActionPreference = 'Stop'
$ErrorActionPreference >> log.txt
Try {
    get-item /not-here 2>&1 >> log.txt
}
catch {
    "`tError caught!" >> log.txt
}
$ErrorActionPreference = 'Ignore'
$ErrorActionPreference >> log.txt
get-item /not-here 2>&1 >> log.txt

$ErrorActionPreference = 'Inquire'
$ErrorActionPreference >> log.txt
get-item /not-here 2>&1 >> log.txt

$ErrorActionPreference = 'Continue'

When we run this script we get prompted when $ErrorActionPreference is set to
Inquire.

PS C:temp> .test.ps1

Confirm
Cannot find path 'C:not-here' because it does not exist.
[Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help (default is "Y"): H
Get-Item: C:temptest.ps1:23
Line |
  23 |  get-item /not-here 2>&1 >> log.txt
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The running command stopped because the user selected the Stop option.

When we examine the log file we see the following:

PS C:temp> Get-Content .log.txt
Continue

Get-Item: C:temptest.ps1:3
Line |
   3 |  get-item /not-here 2>&1 >> log.txt
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Cannot find path 'C:not-here' because it does not exist.

SilentlyContinue
Stop
    Error caught!
Ignore
Inquire

Notes

The redirection operators that do not append data (> and n>) overwrite the
current contents of the specified file without warning.

However, if the file is a read-only, hidden, or system file, the redirection
fails. The append redirection operators (>> and n>>) do not write to a
read-only file, but they append content to a system or hidden file.

To force the redirection of content to a read-only, hidden, or system file,
use the Out-File cmdlet with its Force parameter.

When you are writing to files, the redirection operators use UTF8NoBOM
encoding. If the file has a different encoding, the output might not be
formatted correctly. To write to files with a different encoding, use the
Out-File cmdlet with its Encoding parameter.

Width of output when writing to a file

When you are writing to a file using either Out-File or the redirection
operators, PowerShell formats table output to the file based on the width of
the console it is running within. For instance, when logging table output
to file using a command like Get-ChildItem Env:Path > path.log on a system
where the console width is set to 80 columns, the output in the file is
truncated to 80 characters:

Name                         Value
----                         -----
Path                         C:Program FilesPowerShell7;C:WINDOWS…

Considering that the console width may be set arbitrarily on systems where
your script is run, you may prefer that PowerShell format table output to
files based on a width that you specify instead.

The Out-File cmdlet provides a Width parameter that allows you to set
the width you would like for table output. Rather than having to add
-Width 2000 everywhere you invoke Out-File, you can use the
$PSDefaultParameterValues variable to set this value for all usages of the
Out-File cmdlet in a script. And since the redirection operators (> and
>>) are effectively aliases for Out-File, setting the Out-File:Width
parameter for the whole script impacts the formatting width for the
redirection operators as well. Put the following command near the top of your
script to set Out-File:Width for the whole script:

$PSDefaultParameterValues['out-file:width'] = 2000

Increasing the output width will increase memory consumption when logging
table formatted output. If you are logging a lot of tabular data to file and
you know you can get by with a smaller width, use the smaller width.

In some cases, such as Get-Service output, in order to use the extra width
you will need to pipe the output through Format-Table -AutoSize before
outputting to file.

$PSDefaultParameterValues['out-file:width'] = 2000
Get-Service | Format-Table -AutoSize > services.log

For more information about $PSDefaultParameterValues, see
about_Preference_Variables.

Potential confusion with comparison operators

The > operator is not to be confused with the
Greater-than comparison
operator (often denoted as > in other programming languages).

Depending on the objects being compared, the output using > can appear to be
correct (because 36 is not greater than 42).

PS> if (36 > 42) { "true" } else { "false" }
false

However, a check of the local filesystem can see that a file called 42 was
written, with the contents 36.

PS> dir

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
------          1/02/20  10:10 am              3 42

PS> cat 42
36

Attempting to use the reverse comparison < (less than), yields a system error:

PS> if (36 < 42) { "true" } else { "false" }
ParserError:
Line |
   1 |  if (36 < 42) { "true" } else { "false" }
     |         ~
     | The '<' operator is reserved for future use.

If numeric comparison is the required operation, -lt and -gt should be
used. For more information, see the -gt operator in
about_Comparison_Operators.

See also

  • about_Command_Syntax
  • about_Operators
  • about_Output_Streams
  • about_Path_Syntax
  • Out-File
  • Tee-Object
  • Write-Debug
  • Write-Error
  • Write-Host
  • Write-Information
  • Write-Output
  • Write-Progress
  • Write-Verbose
  • Write-Warning

Всем привет.

В предыдущих двух постах были подробно изложены методы отлова критических и некритических ошибок при работе с PowerShell. Но я решил что будет несправедливым не отметить самые основные моменты, которые возникают в работе если что-то пошло не так. Т.е. переменные и обьекты в PowerShell которые содержат первичную информацию о работе нашего скрипта. Речь пойдет об объекте ErrorRecord, о переменной $Error, о мониторинге возникновения ошибки c помощью переменной $? и кодов возврата, а также упомянем командлет Set-PSDebug и точки прерывания. Поможет нам в этом замечательная книга Попова А. В. «Введение в Windows PowerShell» — СПб.: БХВ-Петербург, 2009.

Поехали.

1. Объект ErrorRecord и поток ошибок.

В PowerShell информация о возникающих ошибках записывается в поток ошибок, который по умолчанию отображается на экране, например:
PS C:> dir «C:Folder doesn’t exist»
Get-ChildItem : Не удается найти путь «C:Folder doesn’t exist»,
так как он не существует.
В строка:1 знак:4
+ dir <<<< «C:Folder doesn’t exist»

Поток ошибок можно перенаправить в текстовый файл с помощью специального оператора 2>, например:
PS C:> dir «C:Folder doesn’t exist» 2>err.txt

Проверим теперь содержимое файла err.txt:
PS C:> Get-Content err.txt
Get-ChildItem : Не удается найти путь «C:Folder doesn’t exist»,
так как он не существует.
В строка:1 знак:4
+ dir <<<< «Folder doesn’t exist» 2> err.txt
Как видите, в файл err.txt полностью записалось сообщение об ошибке, однако никакой дополнительной информации не появилось.

Где произошла ошибка смотрим так
PS C:> $err.InvocationInfo
MyCommand : Get-ChildItem
ScriptLineNumber : 1
OffsetInLine : -2147483648
ScriptName :
Line : $err = dir «C:Folder doesn’t exist» 2>&1
PositionMessage :
 В строка:1 знак:11
 + $err = dir <<<< «C:Folder doesn’t exist» 2>&1
InvocationName : dir
PipelineLength : 1
PipelinePosition : 1
Хотя этот вывод даст нам место скрипта(или непсредственного ввода)
где ошибку интепретирует сама PowerShell, истинное место проблемы надо будет
искать самим.

2. Специальная переменная $Error.

В PowerShell имеется специальная переменная $Error, которая содержит коллекцию (массив) объектов ErrorRecord, соответствующих ошибкам, возникавшим в текущем сеансе работы. Максимальное количество элементов в данной коллекции задается значением переменной $MaximumErrorCount (по умолчанию это 256):
PS C:> $MaximumErrorCount
256

После заполнения массива $Error объекты для вновь возникающих ошибок будут заменять объекты, соответствующие старым ошибкам. Возникновение каждой новой ошибки приводит к смещению элементов в массиве $Error: объект для последней ошибки хранится в первом элементе ($Error[0]), объект для предыдущей ошибки — во втором элементе ($Error[1]) и т. д.
Убедимся, что элемент $Error[0] имеет тип ErrorRecord, и выведем содержимое этого элемента:
PS C:> $Error[0].GetType().FullName
System.Management.Automation.ErrorRecord

PS C:> $Error[0]
Get-ChildItem : Не удается найти путь «C:Несуществующий каталог»,
так как он не существует.
В строка:1 знак:4
+ dir <<<< «Несуществующий каталог»
Естественно, мы можем обращаться ко всем свойствам объекта ErrorRecord:

PS C:> $Error[0].Exception
Не удается найти путь «C:Несуществующий каталог», так как он не существует.

Повторим вывод свойства InvocationInfo
PS C:> $Error[0].InvocationInfo
MyCommand : Get-ChildItem
ScriptLineNumber : 1
OffsetInLine : -2147483648
ScriptName :
Line : $err = dir «C:Folder doesn’t exist» 2>&1
PositionMessage :
 В строка:1 знак:11
 + $err = dir <<<< «C:Folder doesn’t exist» 2>&1
InvocationName : dir
PipelineLength : 1
PipelinePosition : 1

3. Мониторинг возникновения ошибки переменной $?.

В PowerShell имеется логическая переменная $?, которая равна $True, если последняя выполняемая операция завершена успешно, и $False, если во время выполнения последней
операции возникла ошибка. Такая же существует и в Linux.) Например, если выполнить командлет Get-Item для заведомо существующего каталога, то значение переменной $? будет равно $True:
PS C:> Get-Item С:
Каталог:
Mode LastWriteTime Length Name
—- ————- —— —-
d—hs 21.03.2016 12:00 C:

PS C:> $?
True

Если же выполнить этот же командлет для несуществующего каталога, то значение переменной $? будет равно $False:
PS C:> Get-Item С:321
Get-Item : Не удается найти путь «C:321», так как он не существует.
В строка:1 знак:9
Глава 9. Обработка ошибок и отладка 183
+ Get-Item <<<< С:321
PS C:> $?
False

4. Мониторинг возникновения ошибки по коду возврата.

Для внешних команд Windows и сценариев PowerShell определено понятие кода возврата (напомним, что для сценариев PowerShell этот код можно установить с помощью инструкции Exit). В операционной системе код возврата последней команды доступен через переменную среды %ERRORLEVEL%; в оболочке PowerShell данный код возврата хранится в специальной переменной $LASTEXITCODE. При этом, если код возврата равен нулю, то переменной $? присваивается значение $True. Если же код возврата не равен нулю, то считается, что при выполнении данной команды произошла ошибка, и переменной $? присваивается значение $False.

В качестве примера выполним команду интерпретатора cmd.exe, которая устанавливает нулевой код возврата. Для этого можно запустить cmd.exe с ключом /c (выполнить команду и завершить работу интерпретатора) и указать для исполнения команду exit 0:
PS C:> cmd /c exit 0

Проверим значения переменных $LASTEXITCODE и $?:
PS C:> $LASTEXITCODE
0
PS C:> $?
True
Теперь выполним команду интерпретатора cmd.exe с ненулевым кодом возврата (пусть, например, код возврата равен 10):
PS C:> cmd /c exit 10
Вновь проверим переменные $LASTEXITCODE и $?:
PS C:> $?
False
PS C:> $LASTEXITCODE
10

5. Командлет Set-PSDebug и точки прерывания.

Процесс поиска ошибок в сценариях неразрывно связан с отладкой. Поэтому нам стоит упомянуть что основным встроенным инструментом для отладки сценариев является командлет Set-PSDebug. Параметры этого командлета позволяют включить режимы трассировки и пошагового выполнения команд, а также режим обязательного объявления переменных:
-Trace 0 Отключение трассировки
-Trace 1 Включение основного режима трассировки
-Trace 2 Включение полного режима трассировки
-Step Включение режима пошагового выполнения
-Strict Включение режима обязательного объявления переменных
-Off Отключение всех механизмов отладки.

Примеры приводить не буду, назначение ключей очевидно из их названия. Самым интересным является режим пошагового выполнения -Step, который позволяет в любой момент вызвать вложенную командную строку для анализа или изменения состояния интерпретатора. Однако отлаживать более-менее большие сценарии с помощью данного метода часто оказывается неудобно, так как для запуска вложенного сеанса в определенной строке сценария придется каждый раз добираться до этой строки с самого начала сценария (каждую команду при этом
нужно выполнять, нажимая клавишу <A>).

Гораздо удобнее было бы использовать точки прерывания, позволяющие запускать сценарий в автоматическом режиме и приостанавливать выполнение на нужной команде. В PowerShell аналогом установки точки прерывания можно считать вызов метода $Host.EnterNestedPrompt(), например:
PS C:> for ($i=0; $i -lt 10; $i++) {
>> «i = $i»
>> if ($i -eq 5) {
>> «Моя точка прерывания»
>> $Host.EnterNestedPrompt()
>> }
>> }
>>
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
Моя точка прерывания
PS C:>>>

В данном примере на пятой итерации цикла выводится строка «Моя точка прерывания» и вызывается метод $Host.EnterNestedPrompt(). В результате выполнение цикла приостанавливается, и мы попадаем во вложенную командную строку (вид приглашения изменяется на >>>).

Выход из вложенного сеанса с помощью инструкции Exit:
PS C:>>> Exit
PS C:>

Вот так вот.

PowerShell has several redirection operators that can be used to redirect specific type of output to a file. For example, if you want to redirect all errors produced by different cmdlet in your script to a text file, you can use Error redirection to do so.

It is particularly helpful when you want to hide errors from appearing on the screen but need them to identify any possible issues and improving the script. Sometimes, when you have a script deployed in production, you can ask users (who are using your script) for the error redirection file to troubleshoot the script.

To send errors to specified file, use 2> file.name

To append errors to a specified file, use 2>> file.name

Following examples attempts to delete files from c:temp folder and redirects any errors to c:errors.txt file.

PS C:> Get-ChildItem -Path c:temp

Directory: C:temp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         4/24/2016   2:45 PM        972 errors.txt
-a---         4/24/2016   2:48 PM      21085 ex2.docx
-a---         4/24/2016   2:49 PM        274 test.txt
-a---         4/24/2016   2:47 PM       8008 test.xlsx
-a---         4/24/2016   2:49 PM        289 test2.ps1

PS C:> Get-ChildItem -Path C:temp | Remove-Item 2> C:errors.txt
PS C:>

If above command has not resulted in any error, you will not see c:errors.txt or anything in the file. if the command produced any errors, it will be there in the error file. In example above, two documents were open and they were not deleted. notice how errors were not shown on the console but they were redirected to given error file:

PS C:> get-content C:errors.txt
Remove-Item : Cannot remove item C:tempex2.docx: The process cannot access the file 'C:tempex2.docx' because it is being used by another
process.
At line:1 char:31
+ Get-ChildItem -Path C:temp | Remove-Item 2> c:errors.txt
+                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : WriteError: (C:tempex2.docx:FileInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item C:temptest.xlsx: The process cannot access the file 'C:temptest.xlsx' because it is being used by
another process.
At line:1 char:31
+ Get-ChildItem -Path C:temp | Remove-Item 2> c:errors.txt
+                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : WriteError: (C:temptest.xlsx:FileInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
PS C:> Get-ChildItem C:temp

Notice that the error message redirected to the file is same as you would see on the console when not handling (by means of  -ErrorAction, Try/Catch etc.). It shows line number that has thrown the error and helps in troubleshooting the script/code.

2> c:errors.txt in Remove-Item cmdlet in the pipeline is used to direct the errors to given text file (here c:errors.txt). If you need to append to a file instead of overwriting/creating a new one (2> c:errors.txt creates the file if does not exist or overwrites it if it exist), use append operator (2>> c:errors.txt):

PS C:> Get-ChildItem -Path C:temp | Remove-Item 2>> c:errors.txt

One important point to note is, you shouldn’t always be just redirecting errors. There are times when you need to handle errors in a script and take appropriate action. In those cases, its better to use error handling (using try/catch, -ErrorAction parameter of supported cmdlets etc.) to handle the error appropriately.

The output of PowerShell commands is by default displayed in the terminal. But in some situations, it’s more useful to redirect the output to a file in PowerShell. For this, we are going to use the Out-File cmdlet.

There are different ways to output the results of a PowerShell script or command to file. It’s even possible to show the output in the terminal and export it to a file at the same time. And did you know that you can also export only the success, warning, or error results?

In this article

In this article, we are going to take a look at how to write the output to a file in PowerShell. I will also explain how you can append to an existing file or how you can create a log file.

There are a couple of ways to write the output of PowerShell to a file. The most common ways are to use the Out-File cmdlet or the redirection operator >. Other options are to use the Set-Content and Add-Content cmdlet. We are going to focus on the first two, but I will briefly mention the alternative if relevant.

The Out-File cmdlet and redirect operator > allows you to write and append (>>) the PowerShell output to a file. The difference between the two is that the first accepts parameters and the latter doesn’t.

With the Out-File cmdlet we can use the following parameters:

Parameter Description
-Filepath Set the location and name of the file
-Append Append the output to the existing content of the file
-Force Overwrite a read-only file
-NoClobber Prevent overwrite of file
-NoNewLine No newline character will be written.
-Width Limit the number of characters on each line (default 80)
-WhatIf Run in test mode
Out-File cmdlet Parameters

PowerShell Redirect Operator

The redirect operator however doesn’t have any parameters. But it has an advantage compared to Out-File. When using the Out-File cmdlet, only the successful results are exported, so warnings or errors won’t be written to the file.

When using the redirect operator we can specify which stream we want to export:

Operator Description / Stream Write cmdlet
> Success only Write-Output
2> Error only Write-Error
3> Warning only Write-Warning
4> Verbose only Write-Verbose
5> Debug only Write-Debug
6> Information only Write-Information
*> All
PowerShell Redirect Operator

I will explain more about the different streams later, but let’s first take a look at how we can simply write the output to a file in PowerShell.

To write the output to a file all you have to do is pipe the Out-File cmdlet behind your script or command and specify the path. If the file doesn’t exist, then it will be created by the cmdlet:

Get-Process -Name explorer | Out-File -FilePath c:tempprocess.txt

# Same as:
Get-Process -Name explorer > c:tempprocess.txt

# The results
 Get-Content C:tempprocess.txt

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
    132    94,56     158,22     131,45  123364   1 explorer

PS C:>

As you can see, the results of the Get-Process cmdlet is stored in the process.txt file:

powershell write output to file

Powershell Output to File

If you don’t specify any other parameter, then the Out-File cmdlet and redirect operator will overwrite any existing file by default. We can prevent this by adding the -NoClobber parameter to the cmdlet

Get-Process -Name explorer | Out-File c:tempprocess.txt -NoClobber

Note that you can’t prevent overwriting with the redirect operator

If the file already exists, then an error will be thrown:

Don't overwrite file

Don’t overwrite existing files

If you want to output to a file inside a script then I recommend that you use the Test-Path cmdlet first to determine if the file already exists. This way you can write a better solution, like appending a date to the file name, instead of simply trying to write to it:

$exportPath = "C:tempprocess.txt"

If (Test-Path $exportPath) {
    # Show a warning or change the file name here
    Write-Warning "File already exists"
    $exportPath = "C:tempprocess-1.txt" # create something nice with a date or timestamp
}else{
    Get-Process -Name explorer | Out-File $exportPath -NoClobber
}

PowerShell Append to File

Instead of overwriting, we can also append the output to the existing content of the file. For this, we can either use the -append parameter or use the redirect operator >>. In both cases, the contents of the output will be added to the existing file.

You can also append to a non-existing file, both methods will create a new file if the specified file doesn’t exist.

# Append with the Out-File cmdlet
'Apple' | Out-File -FilePath C:tempfruits.txt -Append
Get-Content -Path c:tempfruits.txt

# Result
Apple

# Append with the redirect operator
'Pear' >> C:tempfruits.txt
Get-Content -Path c:tempfruits.txt

# Result
Apple
Pear

When appending output to an existing file the content will be placed on a new line. If you want to have the content on one single line, creating one long string, then you will need to use the Out-File cmdlet with the -NoNewLine parameter.

The newline character is placed after the value that you have added to the file. So it’s important to add the -NoNewLine parameter to the first Output as well.

# Note that you will need to specify NoNewLine for the first entry as well
'BlueBerry;' | Out-File -FilePath C:tempfruits.txt -NoNewline

# Appending more berries
'StrawBerry;' | Out-File -FilePath C:tempfruits.txt -Append -NoNewline
'BlackBerry;' | Out-File -FilePath C:tempfruits.txt -Append -NoNewline
'RaspBerry;' | Out-File -FilePath C:tempfruits.txt -Append -NoNewline
'CranBerry;' | Out-File -FilePath C:tempfruits.txt -Append -NoNewline

To make the result more readable I have added a semi-colon to all values. As you can see all the results are on the same line:

PowerShell Append to File

Append to file with no newline

Using PowerShell Add-Content

Another option to add content to a file is to use the Add-Content cmdlet. One of the biggest advantages of the Add-Content cmdlet is that it allows you to append content to multiple files at once.

Just like with the Out-File cmdlet and redirect operator, the Add-Content cmdlet creates a new file if the file doesn’t exist

So to simply add content to a file we can use the following command:

Add-Content -Path c:tempfile.txt -Value "New line to add"

To add the same content to multiple files we have a couple of parameters to help us. We can use wildcards in the path to specify the files that we want to update. Also, we can exclude files names and even use a filter.

The example below will add the current date to all TXT files in the path c:tempfiles, except in the file with readme in the filename:

Add-Content -Path C:tempfiles*.txt -Value (Get-Date) -Exclude "readme*"

All the files, except the readme files, are updated:

append to file

PowerShell Add-Content

Both the include and exclude parameters allow you to specify a string array of files that you want or do not want to update.

If we take the example from above, we could also use the filter parameter to select only the files that include the word log:

Add-Content -Path C:tempfiles* -Value (Get-Date) -Filter "*log*"

Write only Errors, Warnings, or Success to file

The out-file cmdlet will write only the successful result of your command or script to a file. But sometimes you also want warnings or errors to be outputted as well.

To achieve this, we can use the redirect operator. It allows you to specify which stream you want to output to a file.

Let’s take the script below as an example:

Function Get-ProcessCpu {
    param(
        [Parameter(Mandatory = $true)]$name
    )
    Get-Process -Name $name | select cpu
}
Get-ProcessCpu -name "explorer2" | Out-File C:tempprocess.txt

The process “Explorer2” doesn’t exist, so the Get-Process cmdlet will throw an error. If we run the script like this, then the process.txt file will be completely empty.

However, if we use the redirect operator we can specify which stream we want to output.

# Write all results to the file:
Get-ProcessCpu -name "explorer2" *> C:tempprocess.txt

# Write only the error to the file:
Get-ProcessCpu -name "explorer2" 2> C:tempprocess-error-log.txt

# Write only warnings to a file:
Get-ProcessCpu -name "explorer2" 3> C:tempprocess-error-log.txt

As you can see, the error is written to the text file with the redirect operator:

powershell write output to file

Powershell Write to Log File

Powershell Write to Log File

The best option to write to a log file is to use the Start-Transcript cmdlet, but we can also write our own log function using the Add-Content cmdlet or the redirect operator.

Using the redirect operator will limit your possibilities, but is a great way if you only want to write the errors of a script to a log file:

Function Get-ProcessCpu {
    param(
        [Parameter(Mandatory = $true)]$name
    )
    Get-Process -Name $name | select cpu
}

# Write only errors to a log file
Get-ProcessCpu -name "explorer2" 2>> "C:tempfiles$env:computername-process.log"

But when you are writing messages to a log file you probably want to have a bit more control. With log files it’s important we can see when the event happened and the severity of the event. So what we want to do is add a timestamp and an event level to the log message.

This way we can easily read the log file and identity any errors that have occurred.

# Set log file path
$logFile = "C:tempfiles$env:computername-process.log"

Function Write-Log {
    param(
        [Parameter(Mandatory = $true)][string] $message,
        [Parameter(Mandatory = $false)]
        [ValidateSet("INFO","WARN","ERROR")]
        [string] $level = "INFO"
    )

    # Create timestamp
    $timestamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")

    # Append content to log file
    Add-Content -Path $logFile -Value "$timestamp [$level] - $message"
}

Write-Log -level ERROR -message "String failed to be a string"

The function above is an example of a simple log file creator for PowerShell that allows you to write messages (events) to a log file with the severity and timestamp.

Powershell Write to Log File

Powershell Write to Log File

Wrapping Up

As you have seen there are multiple ways in PowerShell to output the results to a file. To quickly output something to a file you can use the redirect operator or the Out-File cmdlet.

When you want to export the output to a CSV file, then make sure that you read this article. It’s also possible to replace content inside a file using the Replace method.

If you have any questions, just drop a comment below.

  • wisgest

При выполнении компиляции нужно стандартный вывод ошибок направить в файл «error.txt», НО, при этом в терминал тоже должен быть этот же вывод:
g++ test.cpp -o test 2>> error.txt


  • Вопрос задан

    более трёх лет назад

  • 1113 просмотров

Именно ошибок ? тогда проще всего в файл, а потом его прочитать
а если всего подряд, тогда

g++ test.cpp -o test 2>&1 | Tee-Object -Filepath error.txt

Нашёл ещё вариант

invoke-command { 'txt1'; write-error 'err'; 'txt2' } -ErrorVariable e
#пример вызова внешней команды
invoke-command { python 1.py 2>&1 } -ErrorVariable e
$e | Out-File error.txt

Пригласить эксперта


  • Показать ещё
    Загружается…

09 июн. 2023, в 01:21

10000 руб./за проект

09 июн. 2023, в 01:06

50000 руб./за проект

09 июн. 2023, в 00:36

1000 руб./за проект

Минуточку внимания

Как записать в файл лога только ошибки?
Вероятно вы уже встречали не совсем очевидные знаки типа 2>&1
Давайте разберемся что это и как этим пользоваться.

Что бы понимать какие вообще есть потоки, приведу следующую таблицу:

0 stdin Стандартный ввод
1 stdout Стандартный вывод
2 stderr Стандартный вывод ошибок

В Powershell существует больше потоков

Для перенаправления потока
используется комбинация знаков «больше» и амперсанд: >&

Пример:

taskkill -im programm.exe 2>&1

Варианты перенаправления

Перенаправление в файл

Для перенаправления в файл не нужно указывать знак & — он используется только при перенаправлении одного потока в другой

команда 2> файл

Таким образом мы перенаправляем более узкий набор данных(поток ошибок) в более общий(стандартный поток вывода), что бы направить в файл всю имеющуюся информацию, которую в последствии можно использовать для отладки.

Перенаправление потока в другой поток
команда 2>&1

Использование конструкции 1>&2  не предусмотрено, так как не имеет смысла.

Перенаправление с добавлением

Одинарный знак «>» заменяется на двойной и позволяет записывать вывод потока в конец файла

команда 2>> файл
Перенаправление в Null

С помощью перенаправления потока в Null можно убрать из вывода содержимое этого потока.

команда 2>null

Это очень полезно в Powershell, при использовании утилиты psexec, так как даже при успешном выполнении команды возвращается код ошибки 0. Используйте 2>null  если нужно подавить эти строки

Записки администратора

Понравилась статья? Поделить с друзьями:
  • Powershell вывод в консоль ошибок
  • Powershell все ошибки в файл
  • Prinfix ошибка файл не найден обратитесь к администратору
  • Prince of persia warrior within ошибка русский язык ввода
  • Prince of persia the warrior within синтаксическая ошибка