In PowerShell, what’s the difference between Out-File and Set-Content? Or Add-Content and Out-File -append?
I’ve found if I use both against the same file, the text is fully mojibaked.
(A minor second question: > is an alias for Out-File, right?)
Here’s a summary of what I’ve deduced, after a few months experience with PowerShell, and some scientific experimentation. I never found any of this in the documentation 🙁
[Update: Much of this now appears to be better documented.]
Read and write locking
While
Out-Fileis running, another application can read the log file.While
Set-Contentis running, other applications cannot read the log file. Thus never useSet-Contentto log long running commands.Encoding
Out-Filesaves in theUnicode(UTF-16LE) encoding by default (though this can be specified), whereasSet-Contentdefaults toASCII(US-ASCII) in PowerShell 3+ (this may also be specified). In earlier PowerShell versions,Set-Contentwrote content in theDefault(ANSI) encoding.Editor’s note: PowerShell as of version 5.1 still defaults to the culture-specific
Default(“ANSI”) encoding, despite what the documentation claims. If ASCII were the default, non-ASCII characters such asüwould be converted to literal?, but that is not the case:'ü' | Set-Content tmp.txt; (Get-Content tmp.txt) -eq '?'yields$False.This means the defaults of two commands are incompatible, and mixing them will corrupt text, so always specify an encoding.
Formatting
As Bartek explained,
Out-Filesaves the fancy formatting of the output, as seen in the terminal. So in a folder with two files, the commanddir | out-file out.txtcreates a file with 11 lines.Whereas
Set-Contentsaves a simpler representation. In that folder with two files, the commanddir | set-content sc.txtcreates a file with two lines. To emulate the output in the terminal:I believe this formatting has a consequence for line breaks, but I can’t describe it yet.
File creation
Set-Contentdoesn’t reliably create an empty file whenOut-Filewould:In an empty folder, the command
dir | out-file out.txtcreates a file, whiledir | set-content sc.txtdoes not.Pipeline Variable
Set-Contenttakes the filename from the pipeline; allowing you to set a number of files’ contents to some fixed value.Out-Filetakes the data as from the pipeline; updating a single file’s content.Parameters
Set-Contentincludes the following additional parameters:Out-Fileincludes the following additional parameters:For more information about what those parameters are, please refer to help; e.g.
get-help out-file -parameter append.