2013-06-03 6 views
2

так что я могу написать BCD команды в Powershell скрипт, как если бы я был в CMD строке, например:Bcdedit, bcdstore и PowerShell

bcdedit /default '{current}' 

Однако я нужен скрипт, который делает это:

bcdedit /default '{current}' 
bcdedit /set '{otherboot}' description "my description" 

, если он не сделал этого, было бы наоборот:

bcdedit /default '{otherboot}' 
bcdedit /set '{current}' description "my description" 

, что мне нужно сделать, это найти идентификатор т он другой загружается в powershell, и я не знаю, как это сделать. все запросы Google говорят, чтобы сделать это:

$bcdStore=gwmi -name root\wmi -list bcdstore -enableall 
$bcdStore|gm 
$result=$bcdStore.OpenStore("") # can also use explicit file name. 
$store=$result.Store 

, но я понятия не имею, как использовать в магазин, как только я его, и это кажется немного слишком сложным. Я имею в виду, что должен быть более простой способ ... нет?

ответ

5

Я не знаю способ сделать это с помощью WMI, но вы можете использовать bcdedit в сочетании с Select-String:

$otherboot = bcdedit /enum | 
    Select-String "path" -Context 2,0 | 
    ForEach-Object { $_.Context.PreContext[0] -replace '^identifier +' } | 
    Where-Object { $_ -ne "{current}" } 

Объяснение:

Выход bcdedit /enum выглядит примерно так:

Windows Boot Manager 
-------------------- 
identifier    {bootmgr} 
device     partition=\Device\HarddiskVolume1 
description    Windows Boot Manager 
locale     en-US 
... 

Windows Boot Loader 
------------------- 
identifier    {current} 
device     partition=C: 
path     \Windows\system32\winload.exe 
description    Windows 7 
locale     en-US 
... 

Windows Boot Loader 
------------------- 
identifier    {e0610d98-e116-11e1-8aa3-e57ee342122d} 
device     partition=C: 
path     \Windows\system32\winload.exe 
description    DebugEntry 
locale     en-US 
... 

Соответствующие разделы этой продукции являются Windows Boot Loader секции, которые –   в отличие от секции   – Windows Boot Manager имеют path запись.Таким образом, мы можем использовать эту запись, чтобы выбрать только Windows Boot Loader разделы:

Select-String "path" 

Поскольку identifier записи 2 строки до path записей, нам нужно 2 строки PreContext (и не PostContext):

Select-String "path" -Context 2,0 

Теперь мы отобрали follwing два фрагмента с выхода bcdedit /enum:

identifier    {current} 
device     partition=C: 
path     \Windows\system32\winload.exe
identifier    {e0610d98-e116-11e1-8aa3-e57ee342122d} 
device     partition=C: 
path     \Windows\system32\winload.exe

Поскольку мы заинтересованы только в первой строке PreContext мы выбираем эти 2 линии, используя ForEach-Object цикл:

ForEach-Object { $_.Context.PreContext[0] } 

уменьшающей два куска на это:

identifier    {current}
identifier    {e0610d98-e116-11e1-8aa3-e57ee342122d}

, из которого мы удаляем категорию (identifier) посредством замены шнура:

ForEach-Object { $_.Context.PreContext[0] -replace '^identifier +' } 

Правильное выражение '^identifier +' соответствует строке (под), начинающейся со слова «идентификатор», за которым следует одно или несколько пробелов, которое заменяется пустой строкой. После этой замены два чанки сводится к этому:

{current}
{e0610d98-e116-11e1-8aa3-e57ee342122d}

Итак, теперь мы только должны отфильтровать кусок, содержащий {current} и то, что осталось, это идентификатор другой загрузочной записи:

Where-Object { $_ -ne "{current}" } 

После этого переменная $otherboot содержит идентификатор неточной загрузочной записи.

+0

нормально, так что это близко, но он не делает то, что я хочу, если я ввожу $ тест в этой строке следующим образом: | % {$ test = $ _. Context.PreContext [0] -replace '^ identifier +'} ' $ test на самом деле {current}, и я играл с номерами контекста, я попытался выбрать« идентификатор строки », и это не помогло. Я не совсем понимаю, что происходит здесь. Мне кажется, что вы зацикливаете каждую загрузку и пытаетесь найти идентификатор? я прав? Я не обязательно хочу его заменить. если я могу сделать $ test = другой идентификатор загрузки, я мог бы написать: bcedit/default $ test – dwarf

+0

Вы сделали это неправильно. См. Объяснение в обновленном ответе. –

0

Я знаю, что это не полный ответ, но этого может быть достаточно, чтобы вы начали. В приведенном ниже коде отображаются имена дисплеев всех операционных систем, о которых известно BCD.

$cxOptions= new-object System.Management.ConnectionOptions 
$cxOptions.Impersonation=[System.Management.ImpersonationLevel]::Impersonate 
$cxOptions.EnablePrivileges=$true 

$mgmtScope=new-object System.Management.ManagementScope -ArgumentList "root\WMI",$cxOptions 
$mgmtPath=new-object System.Management.ManagementPath -ArgumentList 'root\WMI:BcdObject.Id="{9dea862c-5cdd-4e70-acc1-f32b344d4795}",StoreFilePath=""' 
$mgmtObject=new-object System.Management.ManagementObject -ArgumentList $mgmtScope,$mgmtPath,$null 

# Determine what elements exist in the object and output their value in HEX format 
#$mgmtObject.EnumerateElementTypes().types | % { "{0:X0}" -f $_ } 

$objBCD=$mgmtObject.GetElement(0x24000001) 
$objElements=$objBCD.GetPropertyValue("Element") 

$strOldID="{9dea862c-5cdd-4e70-acc1-f32b344d4795}" 
for ($i=0; $i -lt $objElements.Ids.Count; $i++) { 
    $mgmtPath.Path=$mgmtPath.Path.Replace($strOldID,$objElements.Ids[$i]) 
    $strOldID=$objElements.Ids[$i] 
    $objBCDId=new-object System.Management.ManagementObject -ArgumentList $mgmtScope,$mgmtPath,$null 
    $strOS=$objBCDId.GetElement(0x12000004) 
    $strOS.Element.String 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^