将变量输出("echo")到文本文件

jca*_*pio 35 powershell file-io

我正在针对许多服务器运行PowerShell脚本,并且它将输出记录到文本文件中.

我想捕获脚本当前正在运行的服务器.到目前为止,我有:

$file = "\\server\share\file.txt"
$computername = $env:computername

$computername | Add-Content -Path $file
Run Code Online (Sandbox Code Playgroud)

最后一行在输出文件中添加了问号.哎呀.

如何在PowerShell中将变量输出到文本文件?

big*_*gtv 56

最简单的Hello World示例......

$hello = "Hello World"
$hello | Out-File c:\debug.txt
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 10

注意:以下答案是从Windows PowerShell的角度编写的.
但是,它也适用于跨平台的PowerShell 核心版,除了后者 - 值得称赞 - 始终默认使用无BOM的UTF-8字符编码,这是跨平台和文化最广泛兼容的编码.
.


通过更简洁的替代和背景信息来补充bigtv的有用答案有用的答案:

# > $file is effectively the same as | Out-File $file
# Objects are written the same way they display in the console.
# Default character encoding is UTF-16LE (mostly 2 bytes per char.), with BOM.
# Use Out-File -Encoding <name> to change the encoding.
$env:computername > $file

# Set-Content calls .ToString() on each object to output.
# Default character encoding is "ANSI" (culture-specific, single-byte).
# Use Set-Content -Encoding <name> to change the encoding.
# Use Set-Content rather than Add-Content; the latter is for *appending* to a file.
$env:computername | Set-Content $file 
Run Code Online (Sandbox Code Playgroud)

输出到一个文本文件,你有2个基本选择使用不同的对象表示,并采用不同的默认字符编码:

  • Out-File(或>)/ Out-File -Append(或>>):

    • 适用于任何类型的输出对象,因为PowerShell的默认输出格式应用于输出对象.

      • 换句话说:您获得与打印到控制台时相同的输出.
    • 可以使用参数更改的默认编码UTF-16LE,其中大多数字符编码为2个字节.Unicode编码(如UTF-16LE)的优点是它是一个全局字母表,能够编码所有人类语言的所有字符.-EncodingUnicode

      • PSv5.1 +,你可以改变所使用的编码>,并>>通过该$PSDefaultParameterValues选项变量,采取的事实,即>>>现在有效的别名Out-FileOut-File -Append.例如,要更改为UTF-8,请使用:
        $PSDefaultParameterValues['Out-File:Encoding']='UTF8'
  • Set-Content/ Add-Content:

    • 用于编写已知具有有意义字符串表示类型的字符串和实例,例如.NET基本数据类型(布尔值,整数,...).

      • .psobject.ToString()在每个输出对象上调用方法,这会导致对未明确实现有意义表示的类型进行无意义的表示; [hashtable]实例是一个例子:
        @{ one = 1 } | Set-Content t.txt写入文字System.Collections.Hashtablet.txt,这是的结果@{ one = 1 }.ToString().
    • 可以使用参数更改的默认编码是系统的"ANSI"代码页,这是非Unicode应用程序的单字节特定文化的遗留编码,最常见的是Windows-1252. 请注意,文档当前错误地声称ASCII是默认编码.-EncodingDefault

    • 请注意,其Add-Content目的是内容附加现有文件,它仅等同于Set-Content目标文件尚不存在.
      此外,无论文件的现有内容的编码如何,都会盲目地应用默认或指定的编码.

Out-File/ >/ Set-Content/ Add-Content 所有行为文化敏感,即,如果可用,它们会产生适合当前文化(区域设置)的表示(尽管自定义格式数据可以自由定义其自己的文化不变表示 - 请参阅Get-Help about_format.ps1xml).这与PowerShell的字符串扩展(双引号字符串中的字符串插值)形成对比,后者是文化不变的 - 请参阅我的这个答案.

至于性能:由于Set-Content不必对其输入应用默认格式,因此性能更好.


至于OP的症状Add-Content:

由于$env:COMPUTERNAME不能包含非ASCII字符,Add-Content使用"ANSI"编码的输出应该?在输出中产生字符,最可能的解释是输出文件中预先存在的内容的?一部分,附加到.$fileAdd-Content


jca*_*pio 9

经过一些反复试验,我发现了

$computername = $env:computername
Run Code Online (Sandbox Code Playgroud)

用于获取计算机名称,但$computername通过添加内容发送到文件不起作用.

我也试过了$computername.Value.

相反,如果我使用

$computername = get-content env:computername
Run Code Online (Sandbox Code Playgroud)

我可以使用它将其发送到文本文件

$computername | Out-File $file
Run Code Online (Sandbox Code Playgroud)

  • `Get-Content env:computername`和`$ env:computername`之间有_no_的区别.您的问题使用"添加内容",而您的答案使用"Out-File",它们是具有不同默认编码行为的不同cmdlet.除了编码默认值,"Add-Content"_将添加到预先存在的file_,而"Out-File"总是创建_new_文件/截断(覆盖)现有文件. (3认同)