Поиск по сайту:

Как вывести в файл с помощью PowerShell Out-File


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

Существует несколько способов вывода результатов скрипта или команды PowerShell в файл. Даже возможно показать вывод в терминале и экспортировать его в файл одновременно. И вы знали, что вы также можете экспортировать только успешные, предупреждающие или ошибочные результаты?

В этой статье мы рассмотрим, как записывать вывод в файл в PowerShell. Я также объясню, как вы можете добавить данные в существующий файл или как создать файл журнала.

Powershell записать вывод в файл

Существует несколько способов записать вывод PowerShell в файл. Наиболее распространенные способы - это использовать командлет Out-File или оператор перенаправления >. Другими вариантами являются использование командлетов Set-Content и Add-Content. Мы сосредоточимся на первых двух, но я кратко упомяну альтернативу, если это будет актуально.

Командлет Out-File и оператор перенаправления > позволяют записывать и добавлять (>>) вывод PowerShell в файл. Разница между ними в том, что первый принимает параметры, а последний — нет.

С помощью командлета Out-File мы можем использовать следующие параметры:

-Filepath

Установите местоположение и имя файла

-Append

Добавьте вывод к существующему содержимому файла

-Force

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

-NoClobber

Предотвратить перезапись файла

-NoNewLine

Никакой символ переноса строки не будет записан.

-Width

Ограничьте количество символов в каждой строке (по умолчанию 80)

-WhatIf

Запустите в тестовом режиме

Параметры cmdlet Out-File

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

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

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

ОператорОписание/ПотокНапишите командлет
>Только успехWrite-Output
2>Только ошибкаWrite-Error
3>Только предупреждениеWrite-Warning
4>Только многословноWrite-Verbose
5>Только отладкаWrite-Debug
6>Только информацияWrite-Information
*>Все
Оператор перенаправления PowerShell

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

Чтобы записать вывод в файл, вам нужно просто перенаправить командлет Out-File за вашим скриптом или командой и указать путь. Если файл не существует, то он будет создан командлетом:

Get-Process -Name explorer | Out-File -FilePath c:\temp\process.txt

Same as:
Get-Process -Name explorer > c:\temp\process.txt

The results
 Get-Content C:\temp\process.txt

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

PS C:\>

Как вы можете видеть, результаты команды Get-Process хранятся в файле process.txt:

Вывод PowerShell в файл

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

Get-Process -Name explorer | Out-File c:\temp\process.txt -NoClobber

Обратите внимание, что вы не можете предотвратить перезапись с помощью оператора перенаправления

Если файл уже существует, то будет выброшена ошибка:

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

Если вы хотите вывести данные в файл внутри скрипта, я рекомендую сначала использовать Test-Path, чтобы определить, существует ли файл уже. Таким образом, вы сможете написать более надежное решение, например, добавив дату к имени файла, вместо того чтобы просто пытаться записать в него:

$exportPath = "C:\temp\process.txt"

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

PowerShell Добавить в файл

Вместо перезаписи мы также можем добавлять выходные данные к существующему содержимому файла. Для этого мы можем использовать параметр -append или оператор перенаправления >>. В обоих случаях содержимое вывода будет добавлено к существующему файлу.

Вы также можете добавлять данные в несуществующий файл; оба метода создадут новый файл, если указанный файл не существует.

Append with the Out-File cmdlet
'Apple' | Out-File -FilePath C:\temp\fruits.txt -Append
Get-Content -Path c:\temp\fruits.txt

Result
Apple

Append with the redirect operator
'Pear' >> C:\temp\fruits.txt
Get-Content -Path c:\temp\fruits.txt

Result
Apple
Pear

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

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

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

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

Чтобы сделать результат более читаемым, я добавил точку с запятой ко всем значениям. Как вы видите, все результаты на одной строке:

Добавить в файл без переноса строки

Использование PowerShell Add-Content

Другой способ добавить содержимое в файл - это использовать командлет Add-Content. Одним из основных преимуществ командлета Add-Content является то, что он позволяет добавлять содержимое в несколько файлов сразу.

Так же, как и с командлетом Out-File и оператором перенаправления, командлет Add-Content создает новый файл, если файл не существует.

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

Add-Content -Path c:\temp\file.txt -Value "New line to add"

Чтобы добавить одинаковый контент в несколько файлов, у нас есть несколько параметров, которые помогут нам. Мы можем использовать подстановочные знаки в пути, чтобы указать файлы, которые мы хотим обновить. Также мы можем исключать имена файлов и даже использовать фильтр.

Пример ниже добавит текущую дату ко всем TXT файлам в пути c:\temp\files, за исключением файлов, в названии которых есть 'readme':

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

Все файлы, кроме файлов readme, обновлены:

PowerShell Добавить- Содержимое

Параметры include и exclude позволяют вам указать массив строк файлов, которые вы хотите обновить или не хотите обновлять.

Если взять приведенный выше пример, мы также можем использовать параметр фильтра для выбора только тех файлов, которые содержат слово log:

Add-Content -Path C:\temp\files\* -Value (Get-Date) -Filter "*log*"

Записывайте только ошибки, предупреждения или успешные сообщения в файл

Командлет out-file будет записывать только успешный результат вашей команды или скрипта в файл. Но иногда вы также хотите, чтобы предупреждения или ошибки выводились.

Для достижения этой цели мы можем использовать оператор перенаправления. Он позволяет указать, какой поток вы хотите вывести в файл.

Давайте возьмем следующий скрипт в качестве примера:

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

Процесс «Explorer2» не существует, поэтому командлет Get-Process вызовет ошибку. Если мы запустим скрипт таким образом, то файл process.txt будет совершенно пустым.

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

Write all results to the file:
Get-ProcessCpu -name "explorer2" *> C:\temp\process.txt

Write only the error to the file:
Get-ProcessCpu -name "explorer2" 2> C:\temp\process-error-log.txt

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

Как вы можете видеть, ошибка записывается в текстовый файл с помощью оператора перенаправления:

Powershell запись в файл журнала

Powershell записать в файл журнала

Лучший способ записывать в файл журнала - использовать командлет Start-Transcript, но мы также можем написать собственную функцию журнала, используя командлет Add-Content или оператор перенаправления.

Использование оператора перенаправления ограничит ваши возможности, но это отличный способ, если вы хотите записать только ошибки скрипта в файл журнала:

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:\temp\files\$env:computername-process.log"

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

Таким образом, мы можем легко читать файл журнала и выявлять любые ошибки, которые произошли.

Set log file path
$logFile = "C:\temp\files\$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"

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

Powershell записать в файл журнала

Заключение

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

Когда вы хотите экспортировать вывод в CSV файл, обязательно прочитайте эту статью. Также возможно заменить содержимое внутри файла с помощью метода Replace.

Если у вас есть вопросы, просто оставьте комментарий ниже.