I'm running a PowerShell script against many servers, and it is logging output to a text file.
I'd like to capture the server the script is currently running on. So far I have:
$file = "\\server\share\file.txt"
$computername = $env:computername
$computername | Add-Content -Path $file
This last line adds question marks in the output file. Oops.
How do I output a variable to a text file in PowerShell?
The simplest Hello World example...
Your sample code seems to be OK. Thus, the root problem needs to be dug up somehow. Let's eliminate chance for typos in the script. First off, make sure you put
Set-Strictmode -Version 2.0
in the beginning of your script. This will help you to catch misspelled variable names. Like so,The next part about question marks sounds like you have a problem with Unicode. What's the output when you type the file with Powershell like so,
After some trial and error, I found that
works to get a computer name, but sending
$computername
to a file via Add-Content doesn't work.I also tried
$computername.Value
.Instead, if I use
I can send it to a text file using
Note: The answer below is written from the perspective of Windows PowerShell.
However, it applies to the cross-platform PowerShell Core edition as well, except that the latter - commendably - consistently defaults to BOM-less UTF-8 character encoding, which is the most widely compatible one across platforms and cultures..
To complement bigtv's helpful answer helpful answer with a more concise alternative and background information:
When outputting to a text file, you have 2 fundamental choices that use different object representations and employ different default character encodings:
Out-File
(or>
) /Out-File -Append
(or>>
):Suitable for output objects of any type, because PowerShell's default output formatting is applied to the output objects.
The default encoding, which can be changed with the
-Encoding
parameter, isUnicode
, which is UTF-16LE in which most characters are encoded as 2 bytes. The advantage of a Unicode encoding such as UTF-16LE is that it is a global alphabet, capable of encoding all characters from all human languages.>
and>>
, via the$PSDefaultParameterValues
preference variable, taking advantage of the fact that>
and>>
are now effectively aliases ofOut-File
andOut-File -Append
. To change to UTF-8, for instance, use:$PSDefaultParameterValues['Out-File:Encoding']='UTF8'
Set-Content
/Add-Content
:For writing strings and instances of types known to have meaningful string representations, such as the .NET base data types (Booleans, integers, ...).
.psobject.ToString()
method is called on each output object, which results in meaningless representations for types that don't explicitly implement a meaningful representation;[hashtable]
instances are an example:@{ one = 1 } | Set-Content t.txt
writes literalSystem.Collections.Hashtable
tot.txt
, which is the result of@{ one = 1 }.ToString()
.The default encoding, which can be changed with the
-Encoding
parameter, isDefault
, which is the system's "ANSI" code page, a the single-byte culture-specific legacy encoding for non-Unicode applications, most commonly Windows-1252.Note that the documentation currently incorrectly claims that ASCII is the default encoding.
Note that
Add-Content
's purpose is to append content to an existing file, and it is only equivalent toSet-Content
if the target file doesn't exist yet.Furthermore, the default or specified encoding is blindly applied, irrespective of the file's existing contents' encoding.
Out-File
/>
/Set-Content
/Add-Content
all act culture-sensitively, i.e., they produce representations suitable for the current culture (locale), if available (though custom formatting data is free to define its own, culture-invariant representation - seeGet-Help about_format.ps1xml
). This contrasts with PowerShell's string expansion (string interpolation in double-quoted strings), which is culture-invariant - see this answer of mine.As for performance: Since
Set-Content
doesn't have to apply default formatting to its input, it performs better.As for the OP's symptom with
Add-Content
:Since
$env:COMPUTERNAME
cannot contain non-ASCII characters,Add-Content
's output, using "ANSI" encoding, should not result in?
characters in the output, and the likeliest explanation is that the?
were part of the preexisting content in output file$file
, whichAdd-Content
appended to.