问题
Why can't I edit the description field using bcdedit
in PowerShell?
For example, in cmd.exe
the following command:
bcdedit /set {GUID} description "OS2"
completes successfully, changing the description field for the specified GUID, but when I do the same thing from Powershell, I get the following error:
The set command specified is not valid.
Run "bcdedit /?" for command line assistance.
The parameter is incorrect.
Can someone explain this to me?
回答1:
To pass a value enclosed in {...}
as a literal (as-is) in PowerShell, you must quote it; e.g.:
bcdedit /set "{340E0E1A-01EC-4A33-A850-8D6A09FD4CE9}" description "OS2"
{
and }
, unlike in cmd.exe
, have special meaning in PowerShell when used unquoted (they enclose a script block), which in this case happens to result in {
and }
simply getting removed.
Quoting prevents that.
A generic alternative, available since PSv3, is to use the so-called stop-parsing symbol, --%, which passes all remaining arguments as-is, without interpretation by PowerShell (with the exception of expanding %...%
-enclosed environment-variable references):
bcdedit --% /set {340E0E1A-01EC-4A33-A850-8D6A09FD4CE9} description "OS2"
Optional Background Information
Unless interpolation of PowerShell variables and expression is needed, --%
allows reuse of cmd.exe
command lines as-is, without having to worry about PowerShell's quoting (escaping) requirements.
Generally, PowerShell's metacharacters (characters that have special meaning when unquoted) are different from cmd.exe
's and much more numerous:
In addition to cmd.exe
's metachars.,
& | < >
PowerShell has:
( ) , { } ; @ #
<
, >
, @
and #
only have special meaning at the start of a token.<
and &
, as of PSv5.1, are reserved for future use.
Aside from that, with respect to variable expansion (interpolation):
cmd.exe
only expands%...%
-enclosed variable names (e.g.,%PATH%
), whereas PowerShell requires$
-prefixed variable names (e.g.,$env:PATH
or$HOME
) or$(...)
-enclosed expressions (subexpression operator)- In both interpreters, variable expansion (and, in PowerShell, also subexpression expansion) is also performed inside
"..."
(double-quoted strings).
- In both interpreters, variable expansion (and, in PowerShell, also subexpression expansion) is also performed inside
'...'
(single-quoted strings) are literal strings in PowerShell (contents is used as-is, without interpolation), whereas'
has no special meaning tocmd.exe
at all.
To treat metacharacters as literals, you have two options:
Enclose them in quoted strings:
- Both
cmd.exe
and PowerShell: enclose them in"..."
(but potentially with interpolation of any variable references / subexpressions also enclosed in the string); e.g.,"|"
. - PowerShell only: enclose them in
'...'
; e.g.,'|'
- Both
Escape them individually:
- PowerShell:
`
-escape them (backtick); e.g.,`|
- This also works inside
"..."
, although there it is only needed to escape$
so as to prevent variable / subexpression expansion.
- This also works inside
cmd.exe
:^
-escape them (caret); e.g.,^|
- This only works outside of
"..."
, and sadly, doesn't work for escaping%
to suppress variable expansion - see this answer of mine for the full story.
- This only works outside of
- PowerShell:
来源:https://stackoverflow.com/questions/41030701/unable-to-edit-with-bcdedit-filelds-in-powershell-cmd-exe-command-line-fails