Вы находитесь на странице: 1из 2

Bcdedit.

exe из PowerShell
31.3.2009 — Xaegr

Недавно я столкнулся с необходимостью отредактировать элементы загрузки с помощью утилиты


bcdedit.exe. Эта утилита используется в системах начиная с Vista, для управления хранилищем
конфигурации загрузки, которое заменило boot.ini.

Разумеется я решил запускать утилиту из PowerShell (так как дело происходило на Windows Server
2008R2, то PowerShell было запустить даже проще и быстрее чем cmd.exe ).

Я ознакомился со справкой программы, вызвав её с ключём /?, и хотел выполнить простое действие –
переименовать элемент загрузки. Сначала вызвал bcdedit /enum чтобы посмотреть на список элементов,
и узнать идентификатор того который буду переименовывать (identifier).

PS C:\Windows\System32> bcdedit /enum


...
Windows Boot Loader
-------------------
identifier {c2b02f79-36b4-11dd-9e1b-99d426d57382}
device partition=Q:
path \Windows\system32\winload.exe
description Microsoft Windows Vista
...

И затем попробовал вызвать непосредственно команду переименования.

PS C:\Windows\System32> bcdedit /set {c2b02f79-36b4-11dd-9e1b-99d426d57382} description


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

В чём же проблема? Вроде бы и синтаксис соответствует указанному в справке, и идентификатор


системы я скопировал через буфер обмена, так что ошибок в нём быть не должно… Попробуем создать
простой файл .cmd выводящий имена полученных аргументов, и попробовать ту же команду на нём. Я
назвал его testargs.cmd и поместил в него следующий текст:

@echo Arg1: [%1]


@echo Arg2: [%2]
@echo Arg3: [%3]
@echo Arg4: [%4]
@echo Arg5: [%5]

Весьма просто, неправда ли? Попробуем на нём ту же команду

PS C:\Windows\System32> testargs.cmd /set {c2b02f79-36b4-11dd-9e1b-99d426d57382}


description "Windows Vista"
Arg1: [/set]
Arg2: [-encodedCommand]
Arg3:
[YwAyAGIAMAAyAGYANwA5AC0AMwA2AGIANAAtADEAMQBkAGQALQA5AGUAMQBiAC0AOQA5AGQANAAyADYAZAA1ADcA
MwA4ADIA]
Arg4: [description]
Arg5: ["Windows Vista"]

Неудивительно что bcdedit ругался на синтаксис. Насколько я понимаю, PowerShell увидев


конструкцию в фигурных скобках, посчитал её блоком кода (scriptblock), и решил перед отправкой
команде назначения закодировать с помощью base64 и передать после параметра –encodedCommand.
Сам то PowerShell.exe без проблем разобрался бы с такой конструкцией, но вот bcdedit.exe удивился
Как же обойти этот неприятный эффект? Ну напеример поместить идентификатор в кавычки:

PS C:\Windows\System32> testargs.cmd /set "{c2b02f79-36b4-11dd-9e1b-99d426d57382}"


description "Windows Vista"
Arg1: [/set]
Arg2: [{c2b02f79-36b4-11dd-9e1b-99d426d57382}]
Arg3: [description]
Arg4: ["Windows Vista"]
Arg5: []

Двойные, или одинарные, в данном случае не важно. Главное что PowerShell теперь будет считать этот
аргумент обычной строчкой, и передаст дальше в неизменном виде:

PS C:\Windows\System32> bcdedit /set "{c2b02f79-36b4-11dd-9e1b-99d426d57382}" description


"Windows Vista"
The operation completed successfully.

Второй вариант решения – просто напросто экранировать фигурные скобки, раз уж они смущают
PowerShell. Экранирование в PowerShell выполняется с помощью символа ` (обратный апостроф):

PS C:\Windows\System32> bcdedit /set `{c2b02f79-36b4-11dd-9e1b-99d426d57382`} description


"Windows Vista"
The operation completed successfully.

Проблема решена! Но тема к сожалению не закрыта. Я постараюсь разобрать другие случаи


взаимодействия PowerShell с всевозможными реализациями синтаксиса внешних утилит в других
постах. А вы можете рассказать о встретившихся вам ситуациях, в комментариях

Опубликовано в Command line parsing. Метки: bcdedit, Cmd, Parsing. Комментарии (5) »

Оценить