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

时间:2013-10-01 17:53:27

标签: powershell file-io

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

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

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

$computername | Add-Content -Path $file

最后一行在输出文件中添加了问号。糟糕。

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

5 个答案:

答案 0 :(得分:54)

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

$hello = "Hello World"
$hello | Out-File c:\debug.txt

答案 1 :(得分:8)

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

$computername = $env:computername

用于获取计算机名称,但通过Add-Content$computername发送到文件不起作用。

我也试过$computername.Value

相反,如果我使用

$computername = get-content env:computername

我可以使用

将其发送到文本文件
$computername | Out-File $file

答案 2 :(得分:7)

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

使用更简洁的替代和背景信息来补充bigtv's helpful answer有用的答案:

# > $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 

输出到文本文件时,您有 2个基本选择,它们使用不同的对象表示并使用不同的默认字符编码

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

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

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

      • PSv5.1 + 中,您可以通过>首选项更改>>$PSDefaultParameterValues 使用的编码变量,利用>>>现在实际上是Out-FileOut-File -Append的别名的事实。例如,要更改为UTF-8,请使用:
        $PSDefaultParameterValues['Out-File:Encoding']='UTF8'
  • UTF-16LE / Set-Content

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

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

    • 请注意, Add-Content的目的是将追加 内容附加到现有文件,它只是如果目标文件尚不存在,则相当于Set-Content 此外,默认或指定的编码盲目应用,与文件的现有内容编码无关。

Out-File / > / Set-Content / Add-Content 所有行为文化 - 敏感 ,即他们制作适用于当前文化(语言环境)的表示(如果可用)(尽管自定义格式数据可以自由定义其自己的文化不变表示 - 请参阅documentation)。 这个与PowerShell的字符串扩展(双引号字符串中的字符串插值)形成对比,后者是 culture- 不变 - 请参阅Get-Help about_format.ps1xml矿。

至于效果:由于Set-Content不必对其输入应用默认格式,因此效果更佳。

对于 OP的症状Add-Content

由于$env:COMPUTERNAME不能包含非ASCII字符,Add-Content的输出(使用“ANSI”编码)会导致?字符输出,最有可能的解释是?是输出文件$file预先存在的内容的一部分,Add-Content 附加到

答案 3 :(得分:2)

您的示例代码似乎没问题。因此,需要以某种方式挖出根本问题。让我们消除脚本中拼写错误的机会。首先,确保将Set-Strictmode -Version 2.0放在脚本的开头。这将帮助您捕获拼写错误的变量名称。像这样,

# Test.ps1
set-strictmode -version 2.0 # Comment this line and no error will be reported.
$foo = "bar"
set-content -path ./test.txt -value $fo # Error! Should be "$foo"

PS C:\temp> .\test.ps1
The variable '$fo' cannot be retrieved because it has not been set.
At C:\temp\test.ps1:3 char:40
+ set-content -path ./test.txt -value $fo <<<<
    + CategoryInfo          : InvalidOperation: (fo:Token) [], RuntimeException
    + FullyQualifiedErrorId : VariableIsUndefined

关于问号的下一部分听起来像你有一个Unicode问题。使用Powershell键入文件时的输出是什么,

$file = "\\server\share\file.txt"
cat $file

答案 4 :(得分:0)

这里很简单:

$myVar > "c:\myfilepath\myfilename.myextension"

您也可以尝试:

Get-content "c:\someOtherPath\someOtherFile.myextension" > "c:\myfilepath\myfilename.myextension"