当我跑步时
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize
直接从 PowerShell 运行,代码运行得很好。
但是,当我将这个确切的代码放入文件script.txt
然后运行时
$stdout = Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Get-Content 'script.txt'))) *>&1
我收到以下错误:
Exception calling "Create" with "1" argument(s): "At line:1 char:163
+ ... me, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize
+ ~~~~~~~~~
The string is missing the terminator: "."
是什么导致了这种行为?我必须如何调整代码才能从外部 txt 文件执行脚本?
太长了;博士
这意味着您正在使用Windows PowerShell并且存在字符编码问题。
(这个问题在PowerShell (Core) 7+中不会出现,其一致的默认编码现在是(无 BOM)UTF-8。)
您有两种解决方案选择:
或者:将文件重新保存为带有 BOM 的
script.txt
UTF-8 。-Encoding utf8
或者:与您的通话一起使用Get-Content
(请注意下面的错误警报):一个更简单的替代方法是使用
Invoke-Expression
(但是通常最好避免使用):错误警报:
当将上述推荐与重定向相结合时
*>&1
,错误输出特别消失,即它意外地没有合并到成功输出流(1
)中。这适用于Windows PowerShell(不会修复)和PowerShell(核心)(至少 v7.3.6);相关的错误报告是GitHub issues #10476。
解决方法是在应用之前将
Invoke-Command
调用或Invoke-Expression
管道包含在(...)
分组运算*>&1
符中,例如:该解决方法有一个副作用:使用
(...)
意味着在应用重定向并生成输出之前,首先将所附命令的所有输出全部收集到内存中。背景资料:
您的文件似乎
script.txt
是 UTF-8 编码的,但缺少 BOM,这会导致Windows PowerShell将您的文件误解为 ANSI 编码(即,使用系统旧语言环境的单字节 ANSI 代码页)。这并不明显,但您的文件包含非 ASCII 范围字符:
in是 EN DASH字符,而不是通常的 ASCII 范围,
–
( HYPHEN-MINUS, ) 字符。–AutoSize
U+2013
-
-
U+002D
当 3 字节 UTF-8 编码
–
被误解为 ANSI 时,每个字节本身就变成一个字符,具体来说:–
PowerShell接受
“
(LEFT DOUBLE QUOTATION MARK,U+201C
) 作为通常的 ASCII 范围双引号 QUOTATION MARK 的替代,U+0022
它会导致语法错误,因为缺少右双引号。同样,PowerShell 接受
-
(EN DASH) 代替 ASCII-range-
。有关 PowerShell 支持的语法功能的可互换引号和标点字符的完整列表,请参阅此答案。
然而,为了稳健性,通常最好使用 ASCII 范围字符。
顶部部分中的补救措施可以避免该问题。