所以我可以在powershell脚本中编写bcd命令,就像我在cmd提示符中一样,例如:
bcdedit /default '{current}'
但是我需要一个执行此操作的脚本:
bcdedit /default '{current}'
bcdedit /set '{otherboot}' description "my description"
如果它没有这样做,那将是另一种方式:
bcdedit /default '{otherboot}'
bcdedit /set '{current}' description "my description"
我需要做的是在powershell中找到其他启动的标识符,我不确定如何。所有谷歌搜索都说要这样做:
$bcdStore=gwmi -name root\wmi -list bcdstore -enableall
$bcdStore|gm
$result=$bcdStore.OpenStore("") # can also use explicit file name.
$store=$result.Store
但是我知道如何使用商店,这看起来有点太复杂了。我的意思是应该有一个更简单的方法......不是吗?
答案 0 :(得分: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
记录在path
记录之前是2行,我们需要2行PreContext
(并且没有PostContext
):
Select-String "path" -Context 2,0
现在我们从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
的第一行感兴趣,因此我们使用ForEach-Object
循环选择这两行:
ForEach-Object { $_.Context.PreContext[0] }
将两个块减少到:
identifier {current}
identifier {e0610d98-e116-11e1-8aa3-e57ee342122d}
我们通过字符串替换删除类别(identifier
):
ForEach-Object { $_.Context.PreContext[0] -replace '^identifier +' }
正则表达式'^identifier +'
匹配一个(子)字符串,以“identifier”开头,后跟一个或多个空格,后面用空字符串替换。在更换之后,两个块被简化为:
{current}
{e0610d98-e116-11e1-8aa3-e57ee342122d}
所以现在我们只需要过滤掉包含{current}
的块,剩下的是另一个启动记录的标识符:
Where-Object { $_ -ne "{current}" }
此后,变量$otherboot
包含非当前引导记录的标识符。
答案 1 :(得分: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
}