1

为什么我不能bcdedit在 PowerShell 中编辑描述字段?

例如,在cmd.exe以下命令中:

bcdedit /set {GUID} description "OS2"

成功完成,更改了指定 GUID 的描述字段,但是当我从 Powershell 执行相同操作时,出现以下错误:

The set command specified is not valid.
Run "bcdedit /?" for command line assistance.
The parameter is incorrect.

谁可以给我解释一下这个?

4

1 回答 1

6

要在 PowerShell 中文字(原样)形式传递包含在其中的值,您必须引用{...};例如:

bcdedit /set "{340E0E1A-01EC-4A33-A850-8D6A09FD4CE9}" description "OS2"

{}与 in 不同cmd.exe,是元字符,即在 PowerShell 中不带引号使用时具有特殊含义的字符(它们包含一个脚本块),在这种情况下,这恰好导致{}简单地被删除
引用可以防止这种情况。

或者,您可以单独`转义未引用的元字符
bcdedit /set `{340E0E1A-01EC-4A33-A850-8D6A09FD4CE9`} description "OS2"

自 PSv3 以来可用的通用替代方法是使用所谓的停止解析符号,--%,它按原样传递所有剩余的参数,无需 PowerShell 解释(扩展%...%- 封闭的环境变量引用除外):

bcdedit --% /set {340E0E1A-01EC-4A33-A850-8D6A09FD4CE9} description "OS2"

警告:虽然--%如果您的所有参数都是文字,则按预期工作,就像您的情况一样,通常它会阻止您使用PowerShell 变量表达式作为 / in arguments,并且可能会产生其他意想不到的副作用- 请参阅此答案


可选背景信息

除非需要 PowerShell 变量和表达式的插值,否则--%允许按原样重用cmd.exe命令行,而不必担心 PowerShell 的引用(转义)要求

通常,PowerShell 的元字符(不加引号时具有特殊含义的字符)与 's 不同,cmd.exe而且数量更多

除了's metachars. , cmd.exe

& | < >

PowerShell 具有:

( ) , { } ; @ $ # 

<, >,@并且仅在记号开头#有特殊含义。自 PowerShell 7.0 起保留供将来使用
<

除此之外,关于变量扩展(插值)

  • cmd.exe仅扩展%...%- 封闭的变量名称(例如,%PATH%),而PowerShell 需要$- 前缀的变量名称(例如,$env:PATH$HOME)或$(...)- 封闭的表达式(子表达式运算符)

    • 在这两种解释器中,变量扩展(以及,在 PowerShell 中,还有子表达式扩展)也在内部"..."(双引号字符串)执行。
  • '...'(单引号字符串)是PowerShell 中的文字字符串(内容按原样使用,没有插值),而'根本没有特殊含义cmd.exe

要将元字符视为文字,您有两种选择:

  • 将它们括在带引号的字符串中:

    • 两者cmd.exe和 PowerShell:将它们包含在其中"..."(但可能会插入也包含在字符串中的任何变量引用/子表达式);例如,"|"
    • 仅限 PowerShell:将它们括在'...'; 例如,'|'
  • 单独逃脱它们

    • PowerShell:-`转义它们(反引号);例如,`|
      • 这也适用于内部"...",尽管它只需要转义$以防止变量/子表达式扩展。
    • cmd.exe: -^转义它们(插入符号);例如,^|
      • 这仅适用于 之外"..."可悲的是,它不适用于转义%以抑制变量扩展 - 请参阅此答案以获取完整故事。
于 2016-12-08T03:17:13.690 回答