By default, the output of PowerShell commands is displayed on the terminal. However, in some cases, redirecting the output to a file via PowerShell is more useful. We'll utilise the Out-File cmdlet to accomplish this.
There are several options for saving the results of a PowerShell script or command. It's also feasible to display the result in the terminal while also exporting it to a file. Also, did you know that you can export only the results that are successful, warnings, or errors?
In this post, we'll look at how to use PowerShell to save the output to a file. I'll also go through how to append to an existing file and how to make a log file.
There are a few options for saving PowerShell output to a file. The Out-File cmdlet and the redirection operator > are the most frequent methods. Set-Content and Add-Content cmdlets are two other alternatives. We'll concentrate on the first two, but I'll address the option briefly if it's pertinent.
You can write and append (>>) PowerShell output to a file using the Out-File cmdlet and redirect operator >. The distinction is that the first allows parameters while the second does not.
We can use the following parameters with the Out-File cmdlet:
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
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 when 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
I'll go through the different streams in more detail later, but for now, let's look at how we can simply write the output to a file in PowerShell.
Simply pipe the Out-File cmdlet behind your script or command and give the path to save the output to a file. If the file does not already exist, the cmdlet will create it:
"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:\>"
As you can see, the Get-Process cmdlet returns the following results in the process.txt file:
By default, the Out-File cmdlet and redirect operator overwrite any existing file if you don't supply any other parameters. The -NoClobber argument to the cmdlet can be used to prevent this.
"Get-Process -Name explorer | Out-File c:\temp\process.txt -NoClobber"
You can't use the redirect operator to prevent overwriting.
An error will be thrown if the file already exists:
If you wish to output to a file from within a script, I recommend first checking using the Test-Path cmdlet to see if the file already exists. Instead of merely trying to write to it, you can write a better solution, such as appending a date to the file name:
"$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
}"
We can append the output to the existing content of the file instead of overwriting it. We may either use the -append argument or the redirect operator >> to accomplish this. The contents of the output will be appended to the existing file in both circumstances.
You can also append to an existing file that does not exist; both methods will create a new file if the requested file does not exist.
"# 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"
The content will be placed on a new line when adding output to an existing file. Use the Out-File cmdlet with the -NoNewLine parameter if you want the content to be on a single line, creating a single lengthy string.
After you've added a value to the file, you'll see a newline character. As a result, the -NoNewLine argument must also be added to the first Output.
"# 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"
I added a semi-column to all values to make the result more readable. All of the results, as you can see, are on the same line:
The Add-Content cmdlet is another way to add content to a file. The ability to append content to several files at once is one of the most powerful features of the Add-Content cmdlet.
In the same way that the redirect operator produces a new file with the Out-File cmdlet, the Add-Content cmdlet generates a new file if the file doesn't exist.
So we can use the following command to simply add content to a file:
"Add-Content -Path c:\temp\file.txt -Value "New line to add""
We can use a few options to help us add the identical content to numerous files. To define the files we wish to update, we can use wildcards in the path. We can also use a filter and exclude file names.
The example below will add the current date to all TXT files in the path c:\temp\files, except in the file with readme in the filename:
"Add-Content -Path C:\temp\files\*.txt -Value (Get-Date) -Exclude "readme*""
All the files, except the readme files, are updated:
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 go back to the previous example, we can use the filter option to select only the files that contain the term log:
"Add-Content -Path C:\temp\files\* -Value (Get-Date) -Filter "*log*""
Only the successful outcome of your command or script will be written to a file using the out-file cmdlet. However, there are situations when you want cautions or errors to be outputted as well.
The redirect operator can be used to accomplish this. It allows you to choose which stream should be saved to a file.
Consider the following script as an example:
"Function Get-ProcessCpu {
param(
[Parameter(Mandatory = $true)]$name
)
Get-Process -Name $name | select cpu
}
Get-ProcessCpu -name "explorer2" | Out-File C:\temp\process.txt"
The Get-Process cmdlet will return an error since the process "Explorer2" does not exist. The process.txt file will be absolutely empty if we run the script like this.
We can, however, specify which stream we wish to output if we use the redirect operator.
"# 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"
As you can see, the redirect operator is used to write the error to a text file:
The Start-Transcript cmdlet is the best option for writing to a log file, but we can also use the Add-Content cmdlet or the redirect operator to create our own log function.
Powershell Creating 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:\temp\files\$env:computername-process.log""
The Start-Transcript cmdlet is the best option for writing to a log file, but we can also use the Add-Content cmdlet or the redirect operator to create our own log function.
The redirect operator limits your options, but it's a fantastic way to write a script's errors to a log file: However, if you're writing messages to a log file, you'll probably want a little more control. It's critical to be able to see when an incident occurred and the severity of the occurrence when using log files. So, to the log message, we'd like to add a timestamp and an event level.
"# 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""
We can easily read the log file and identify any mistakes that have happened in this manner.
The above function is an example of a simple PowerShell log file creator that allows you to write messages (events) to a log file with the severity and timestamp.
As you can see, PowerShell offers a variety of options for saving results to a file. You can use the redirect operator or the Out-File cmdlet to quickly output something to a file
Make sure you read this post if you want to export the output to a CSV file. The Replace technique can also be used to replace content within a file.
Please leave a remark below if you have any questions.