so i can write bcd commands in a powershell script as if i were in a cmd prompt, for example:
bcdedit /default '{current}'
however i need a script that does this:
bcdedit /default '{current}'
bcdedit /set '{otherboot}' description "my description"
if it didnt do that, it would be the other way around:
bcdedit /default '{otherboot}'
bcdedit /set '{current}' description "my description"
what i need to do is find the identifier of the other boot in powershell and im not sure how. all google searches say to do this:
$bcdStore=gwmi -name root\wmi -list bcdstore -enableall
$bcdStore|gm
$result=$bcdStore.OpenStore("") # can also use explicit file name.
$store=$result.Store
but i have no idea how to use the store once i have it and this seems a little too complicated. i mean there should be an easier way... no?
I don't know of a way to do it with WMI, but you could use bcdedit
in combination with Select-String
:
$otherboot = bcdedit /enum |
Select-String "path" -Context 2,0 |
ForEach-Object { $_.Context.PreContext[0] -replace '^identifier +' } |
Where-Object { $_ -ne "{current}" }
Explanation:
The output of bcdedit /enum
looks roughly like this:
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
...
The relevant sections of this output are the Windows Boot Loader
sections, which – unlike the Windows Boot Manager
section – have a path
record. Thus we can use this record to select only the Windows Boot Loader
sections:
Select-String "path"
Since the identifier
records are 2 lines before the path
records, we need 2 lines of PreContext
(and no PostContext
):
Select-String "path" -Context 2,0
Now we have selected the follwing two chunks from the output of 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
Since we're only interested in the first line of the PreContext
we select these 2 lines using a ForEach-Object
loop:
ForEach-Object { $_.Context.PreContext[0] }
which reduces the two chunks to this:
identifier {current}
identifier {e0610d98-e116-11e1-8aa3-e57ee342122d}
from which we remove the category (identifier
) via string replacement:
ForEach-Object { $_.Context.PreContext[0] -replace '^identifier +' }
The regular expression '^identifier +'
matches a (sub)string starting with the word "identifier" followed by one or more spaces, which is replaced with the empty string. After this replacement the two chunks are reduced to this:
{current}
{e0610d98-e116-11e1-8aa3-e57ee342122d}
So now we only need to filter out the chunk containing {current}
and what's left is the identifier of the other boot record:
Where-Object { $_ -ne "{current}" }
After this, the variable $otherboot
contains the identifier of the not-current boot record.