使用 PowerShell 修改 Windows BCD





5.00/5 (6投票s)
在 PowerShell 中处理 Windows BCD 存储
背景
由于 BCD 的复杂性,本文将不会深入介绍 BCD。本文旨在演示管理 BCD 存储区的经过测试的技术。对于本文,所有 BCD 操作都在本地进行。此外,BCD 的 WMI 提供程序需要管理员权限。
警告
代码更新
为解决 COM 错误,增加了对 PowerShell 5 的支持。
访问 BCD 存储区
本文将使用 WbemScripting.SWbemLocator
对象来访问 BCD 提供程序。在并排比较中,使用 System.Management
命名空间的 C# 应用程序和使用 WbemScripting
的 PowerShell 脚本使用相同的资源:wmiprvse
、wmiutils
、wbemsvc
、wbemcomn2
、wbemprox
、bcdprov
和 bcdsrv
(以及其他)。对于 PowerShell,使用 WMI 脚本 API 更为容易。通过仅使用 COM 对象,只需几个(简单的)函数即可访问 BCD WMI 提供程序。
获取 static
类 BcdStore
的实例
function Get-StaticBcdStore {
$SWbemLocator = New-Object -ComObject WbemScripting.SWbemLocator
$wmi = $SWbemLocator.ConnectServer(".","root\wmi")
$wmi.Get("BcdStore")
}
四个 COM 辅助函数
访问方法参数
function New-InParameter {
Param([Parameter(Position=0)]$Method, [Parameter(ValueFromPipeLine=$true)]$Object)
$Object.Methods_.Item($Method).InParameters.SpawnInstance_()
}
访问属性
function Get-PropertyValue {
Param([Parameter(Position=0)]$Property, [Parameter(ValueFromPipeLine=$true)]$Object)
$Object.Properties_.Item($Property).Value
}
function Set-PropertyValue {
Param([Parameter(Position=0)]$Property, [Parameter(Position=1)]$Value,
[Parameter(ValueFromPipeLine=$true)]$Object)
$Object.Properties_.Item($Property).Value=$Value
}
方法执行和参数返回值
function Invoke-Method {
Param([Parameter(Position=0)]$Method, [Parameter(Position=1)]$ParameterNames,
[Parameter(Position=2)]$ParameterValues,
[Parameter(ValueFromPipeLine=$true)]$Object)
if($ParameterNames -eq $null -or $ParameterValues -eq $null) {
# If the method has required parameters: "The remote procedure call failed."
$Object.ExecMethod_($Method)
}
else {
$in = $Object.Methods_.Item($Method).InParameters.SpawnInstance_()
if($ParameterNames.GetType() -eq [System.String]) {
$prop = $in.Properties_.Item($ParameterNames)
$prop.GetType().InvokeMember("Value",
[System.Reflection.BindingFlags]::SetProperty,$null,$prop,@($ParameterValues))
}
else {
for($i = 0; $i -lt $ParameterNames.LongLength; $i++) {
if($ParameterValues[$i] -ne $null) {
$prop = $in.Properties_.Item($ParameterNames[$i])
if($ParameterValues[$i] -is [array]) {
$prop.GetType().InvokeMember("Value",
[System.Reflection.BindingFlags]::SetProperty,
$null,$prop,@(,$ParameterValues[$i]))
} else {
$prop.GetType().InvokeMember("Value",
[System.Reflection.BindingFlags]::SetProperty,
$null,$prop,@($ParameterValues[$i]))
}
}
}
}
$Object.ExecMethod_($Method, $in)
}
}
实现 BCD WMI 方法
BcdStore
相关的函数和属性、仅与 BcdObject
相关的函数和属性,以及与 BcdElements
相关且包含共享属性的函数和属性。在实现这些方法时,任何 out 参数都用作函数的返回值,否则,返回值将是一个布尔值,指示操作的成功或失败。处理 BCD 存储区
要访问存储区并检索项目,将使用以下方法
function Open-Store {
Param(
[Parameter(Position=0)][string]$File="",
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "OpenStore" "File" $File | Get-PropertyValue "Store"
}
function Open-Object {
Param(
[Parameter(Position=0)][string]$Id,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "OpenObject" "Id" $Id | Get-PropertyValue "Object"
}
function Enumerate-Objects {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "EnumerateObjects" "Type" $Type | Get-PropertyValue "Objects"
}
要打开 BCD 存储区,必须指定 BCD 文件名。空字符串表示系统存储区。获取 BCD 对象需要对象的 GUID 标识。枚举 BCD 对象需要一个对象类型。
$bootmanager = Get-StaticBcdStore | Open-Store -file "" |
Open-Object "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"
$bootmanager.Properties_
在此示例中,使用 Windows 引导管理器(Windows Boot Manager)的已知 GUID 从系统存储区获取引导管理器,并输出 COM 属性。结果仅为 BcdObject
属性:Id
(即已知 GUID
)、StoreFilePath
(因为在系统存储区中,所以为空)和 Type
(即 0x10100002)。
在上一个示例中,通过使用已知 GUID 显式检索了引导管理器。但是;也可以通过其类型来检索此元素。
$bootmanagers = Get-StaticBcdStore | Open-Store "" |
Enumerate-Objects ([uint32]"0x10100002")
$bootmanagers[0].Properties_
或
$bootmanagers = Get-StaticBcdStore | Open-Store "" | Enumerate-Objects ([uint32]"0x10000002")
$bootmanagers[0].Properties_
这些示例指出了按类型定义枚举对象的能力。在第二个示例中,对象类型被泛化,以指示任何应用程序代码为 Windows 引导管理器的应用程序类型对象。
要创建 BCD 存储区和 BCD 对象,将使用以下两个方法
function Create-Store {
Param(
[Parameter(Position=0)][string]$File,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "CreateStore"
"File" $File | Get-PropertyValue "Store"
}
function Create-Object {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][string]$Id,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "CreateObject"
"Id","Type" $Id,$Type | Get-PropertyValue "Object"
}
与 OpenStore
方法类似,BcdStore
的 CreateStore
方法需要一个文件名。在 BCD 存储区中创建对象需要一个类型和一个可选的 GUID 或已知 GUID。
Get-StaticBcdStore | Create-Store "$env:TEMP\BCD-Demo" `
| Create-Object ([uint32]"0x10100001")
"{a5a30fa2-3d06-4e9f-b5f4-a01df9d1fcba}"
在此示例中,使用固件引导管理器(Firmware Boot Manager)的已知 GUID 和固件引导管理器(Firmware Boot Manager)的对象类型来创建:固件引导管理器。Id
参数是可选的。要创建新对象,只需传递对象类型,对象的 Id 将由提供程序生成的 GUID 填充。但是,许多对象,如这个固件引导管理器,只能通过已知的 GUID 和类型组合来创建。
处理 BCD 对象
设置元素需要 BcdObject
提供的。这些方法共有的特点是使用 Type
来定义要操作的对象元素。Microsoft 的 MSDN 提供了相当完整的(尽管不总是准确的)枚举列表。我的意思是,一些枚举值可能被定义为特定类型,但它们实际上不是该类型,而其他缺失的枚举值——尽管它们可以用现有值替代。
以下方法用于从 BcdObject
中检索元素数据
function Enumerate-Elements {
Param([Parameter(Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Invoke-Method "EnumerateElements" | Get-PropertyValue "Elements"
}
function Get-Element {
Param([Parameter(Position=0)][uint32]$Type,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "GetElement"
"Type" $Type | Get-PropertyValue "Element"
}
function Enumerate-ElementTypes {
Param([Parameter(Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Invoke-Method "EnumerateElementTypes" | Get-PropertyValue "Types"
}
要获取元素、元素类型和值的列表,只需执行以下操作
$bootmanager = Get-StaticBcdStore | Open-Store -file "" |
Open-Object "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"
$bootmanager | Enumerate-ElementTypes | % {
(Get-Element -Type $_ -BcdObject $bootmanager).Properties_
}
至于设置元素数据,以下方法将在后面演示,但名称如 SetBooleanElement
和 SetStringElement
,它们不言自明。
function Set-StringElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][string]$String,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetStringElement"
"Type","String" $Type,$String | Get-PropertyValue "ReturnValue"
}
function Set-BooleanElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][bool]$Boolean,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetBooleanElement"
"Type","Boolean" $Type,$Boolean | Get-PropertyValue "ReturnValue"
}
function Set-IntegerElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)]$Integer,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetIntegerElement"
"Type","Integer" $Type,$Integer | Get-PropertyValue "ReturnValue"
}
function Set-ObjectElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][string]$Id,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetObjectElement"
"Type","Id" $Type,$Id | Get-PropertyValue "ReturnValue"
}
一些方法将接受值数组,应使用 @()
传递这些值。
function Set-ObjectListElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)]$Ids,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetObjectListElement"
"Type","Ids" $Type,$Ids | Get-PropertyValue "ReturnValue"
}
function Set-IntegerListElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)]$Integers,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetIntegerListElement"
"Type","Integers" $Type,$Integers | Get-PropertyValue "ReturnValue"
}
设置设备数据要复杂得多,也将在后面演示
function Set-FileDeviceElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][int]$DeviceType,
[Parameter(Position=2)][string]$AdditionalOptions,
[Parameter(Position=3)][string]$Path,
[Parameter(Position=4)][uint32]$ParentDeviceType,
[Parameter(Position=5)][string]$ParentAdditionalOptions,
[Parameter(Position=6)][string]$ParentPath,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$parameterNames = "Type","DeviceType","AdditionalOptions",
"Path","ParentDeviceType","ParentAdditionalOptions","ParentPath"
$parameterValues = $Type,$DeviceType,$AdditionalOptions,
$Path,$ParentDeviceType,$ParentAdditionalOptions,$ParentPath
$BcdObject | Invoke-Method "SetFileDeviceElement"
$parameterNames $parameterValues | Get-PropertyValue "ReturnValue"
}
function Set-PartitionDeviceElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][int]$DeviceType,
[Parameter(Position=2)][string]$AdditionalOptions,
[Parameter(Position=3)][string]$Path,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$parameterNames = "Type","DeviceType",
"AdditionalOptions","Path"
$parameterValues = $Type,$DeviceType,$AdditionalOptions,$Path
$BcdObject | Invoke-Method "SetPartitionDeviceElement"
$parameterNames $parameterValues | Get-PropertyValue "ReturnValue"
}
BcdObject
提供了更多方法,并在本文后面的代码中包含,尽管本文未涵盖。
处理 BCD 元素
最后一个介绍 BCD 方法的部分将介绍 BCD 对象的实际元素。在前面的部分中,我们介绍了如何使用 BcdStore
对象来打开和创建对象,并简要提及了如何使用 BcdObject
来设置元素数据。要从元素中获取特定信息,我们必须访问元素的属性。string
元素有一个 String
属性,布尔元素有一个 Boolean
属性,依此类推。
function Get-String {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdStringElement)
Get-PropertyValue "String" -Object $BcdStringElement
}
function Get-Integer {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdIntegerElement)
Get-PropertyValue "Integer" -Object $BcdIntegerElement
}
function Get-Boolean {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdBooleanElement)
Get-PropertyValue "Boolean" -Object $BcdBooleanElement
}
对于对象列表
function Get-Integers {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdIntegerListElement)
Get-PropertyValue "Integers" -Object $BcdIntegerListElement
}
function Get-Ids {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdObjectListElement)
Get-PropertyValue "Ids" -Object $BcdObjectListElement
}
对于设备对象
function Get-Device {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdDeviceElement)
$BcdDeviceElement | Get-PropertyValue "Device"
}
这将是获取 BCD 存储区数据的最后一个演示。(压轴好戏:获取设备数据。)
$mem = Get-StaticBcdStore | Open-Store "" |
Open-Object "{b2721d73-1db4-4c62-bf78-c548a880142d}"
$dev = $mem | Get-Element
-Type ([BcdLibraryElementTypes]::Device_ApplicationDevice) | Get-Device
$dev.Properties_
此示例获取 Windows 内存测试程序(Windows Memory Tester)并检索设备数据。此方法对于通过代码评估设置各种设备元素的属性非常有用。
最后,重头戏
现在…本文的最终目标是提供从 PowerShell 修改 BCD 存储区的实际示例。
从头开始构建 BCD 存储区
对于第一个演示,将使用实时系统存储区的 bcdedit
输出在代码中生成新的 BCD 存储区。生成的 BCD 存储区将创建一个已清理、重新格式化并在部署场景中重新映像的驱动器上。bcdedit
的大部分输出已按对象依赖关系重新排序。枚举器和已知 GUID 变量在本文末尾的代码中提供。
. ("$PSScriptRoot\PowershellBcd.ps1")
Get-StaticBcdStore | Create-Store -File "$env:TEMP\BCD-TEMP" | Out-Null
$bcdFile = "S:\boot\BCD"
if(Test-Path $bcdFile) {
Remove-Item -Path $bcdFile | Out-Null
}
$sDrive = Get-DosDevice "S:"
# Windows OS (will be C after reboot)
$cDrive = Get-DosDevice "W:"
$BcdStore = Get-StaticBcdStore | Create-Store -File $bcdFile
$BcdStore | Import-Store "$env:TEMP\BCD-TEMP" | Out-Null
*BCD WMI 提供程序似乎没有实现 QueryDosDevice
——与 bcdedit
不同,在设置 Device
属性时,它不接受卷标。此外,虽然从头开始构建 BCD 存储区会生成一个功能齐全的存储区,并且操作系统能够正常启动、休眠和恢复,但启动到 WinRE 总是会导致 BCD 存储区重建。要使存储区正常工作,必须导入一个“虚拟”存储区。这会生成一个功能正常的 BCD 存储区。(此解决方案可在此链接找到。)
EMS 设置 | |
------------ | |
标识符 | {0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9} |
bootems | 是 |
$BcdStore | Create-Object -Id $emssettings -Type ([uint32]"0x20100000") | `
Set-BooleanElement ([BcdLibraryElementTypes]::Boolean_EmsEnabled) 1 | Out-Null
调试器设置 | |
----------------- | |
标识符 | {4636856e-540f-4170-a130-a84776f4c654} |
debugtype | 串口 |
debugport | 1 |
baudrate | 115200 |
$debugger = $BcdStore | Create-Object -Id $dbgsettings -Type ([uint32]"0x20100000")
$debugger | Set-IntegerElement
([BcdLibraryElementTypes]::Integer_DebuggerType) 0 | Out-Null
$debugger | Set-IntegerElement
([BcdLibraryElementTypes]::Integer_SerialDebuggerPort) 1 | Out-Null
$debugger | Set-IntegerElement
([BcdLibraryElementTypes]::Integer_SerialDebuggerBaudRate) 115200 | Out-Null
RAM 缺陷 | |
----------- | |
标识符 | {5189b25c-5558-4bf2-bca4-289b11bd29e2} |
$BcdStore | Create-Object -Id $badmemory -Type ([uint32]"0x20100000") | Out-Null
全局设置 | |
--------------- | |
标识符 | {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e} |
inherit | {4636856e-540f-4170-a130-a84776f4c654} |
{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9} | |
{5189b25c-5558-4bf2-bca4-289b11bd29e2} |
$global = $BcdStore | Create-Object -Id $globalsettings -Type ([uint32]"0x20100000") | `
Set-ObjectListElement ([BcdLibraryElementTypes]::ObjectList_InheritedObjects) `
@($dbgsettings,$emssettings,$badmemory) | Out-Null
恢复加载程序设置 | |
---------------------- | |
标识符 | {1afa9c49-16ab-4a5c-901b-212802da9460} |
inherit | {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e} |
$BcdStore | Create-Object -Id $resumeloadersettings -Type ([uint32]"0x20200004") | `
Set-ObjectListElement ([BcdLibraryElementTypes]::ObjectList_InheritedObjects)
@($globalsettings) | Out-Null
Hypervisor 设置 | |
------------------- | |
标识符 | {7ff607e0-4395-11db-b0de-0800200c9a66} |
hypervisordebugtype | 串口 |
hypervisordebugport | 1 |
hypervisorbaudrate | 115200 |
$hypervisor = $BcdStore | Create-Object
-Id $hypervisorsettings -Type ([uint32]"0x20200003")
$hypervisor | Set-IntegerElement
([BcdOSLoaderElementTypes]::Integer_HypervisorDebuggerType) 0 | Out-Null
$hypervisor | Set-IntegerElement
([BcdOSLoaderElementTypes]::Integer_HypervisorDebuggerPortNumber) 1 | Out-Null
$hypervisor | Set-IntegerElement
([BcdOSLoaderElementTypes]::Integer_HypervisorDebuggerBaudrate) 115200 | Out-Null
引导加载程序设置 | |
-------------------- | |
标识符 | {6efb52bf-1766-41db-a6b3-0ee5eff72bd7} |
inherit | {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e} |
{7ff607e0-4395-11db-b0de-0800200c9a66} |
$BcdStore | Create-Object -Id $bootloadersettings -Type ([uint32]"0x20200003") | `
Set-ObjectListElement ([BcdLibraryElementTypes]::ObjectList_InheritedObjects)
@($globalsettings,$hypervisorsettings) | Out-Null
Windows 内存测试程序 | |
--------------------- | |
标识符 | {b2721d73-1db4-4c62-bf78-c548a880142d} |
device | partition=S |
路径 | \boot\memtest.exe |
description | Windows 内存诊断 |
locale | en-US |
inherit | {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e} |
badmemoryaccess | 是 |
$memorytester = $BcdStore | Create-Object -Id $memdiag
-Type ([uint32]"0x10200005")
$memorytester | Set-PartitionDeviceElement
([BcdLibraryElementTypes]::Device_ApplicationDevice) 2 "" $sDrive | Out-Null
$memorytester | Set-StringElement
([BcdLibraryElementTypes]::String_ApplicationPath) "\boot\memtest.exe" | Out-Null
$memorytester | Set-StringElement
([BcdLibraryElementTypes]::String_Description) "Windows Memory Diagnostic" | Out-Null
$memorytester | Set-StringElement
([BcdLibraryElementTypes]::String_PreferredLocale) "en-US" | Out-Null
$memorytester | Set-ObjectListElement
([BcdLibraryElementTypes]::ObjectList_InheritedObjects) @($globalsettings) | Out-Null
$memorytester | Set-BooleanElement
([BcdLibraryElementTypes]::Boolean_AllowBadMemoryAccess) 1 | Out-Null
从休眠中恢复 | |
--------------------- | |
标识符 | {ebe94447-1944-11e4-95c4-dd9a4e7158f6} |
device | partition=C |
路径 | \windows\system32\winresume.exe |
description | Windows 恢复应用程序 |
locale | en-US |
inherit | {1afa9c49-16ab-4a5c-901b-212802da9460} |
filedevice | partition=C |
filepath | \hiberfil.sys |
debugoptionenabled | 否 |
$hibernate = $BcdStore | Create-Object ([uint32]"0x10200004")
# Get generated GUID
$resume = $hibernate | Get-Id
$hibernate | Set-PartitionDeviceElement
([BcdLibraryElementTypes]::Device_ApplicationDevice) 2 "" $cDrive | Out-Null
$hibernate | Set-StringElement
([BcdLibraryElementTypes]::String_ApplicationPath)
"\Windows\system32\winresume.exe" | Out-Null
$hibernate | Set-StringElement
([BcdLibraryElementTypes]::String_Description) "Windows Resume Application" | Out-Null
$hibernate | Set-StringElement
([BcdLibraryElementTypes]::String_PreferredLocale) "en-US" | Out-Null
$hibernate | Set-ObjectListElement
([BcdLibraryElementTypes]::ObjectList_InheritedObjects) @($resumeloadersettings) | Out-Null
$hibernate | Set-PartitionDeviceElement
([BcdOSLoaderElementTypes]::Device_OSDevice) 2 "" $cDrive | Out-Null
$hibernate | Set-StringElement
([BcdOSLoaderElementTypes]::String_SystemRoot) "\hiberfil.sys" | Out-Null
$hibernate | Set-BooleanElement
([BcdResumeElementTypes]::Boolean_DebugOptionEnabled) 0 | Out-Null
设备选项 | |
-------------- | |
标识符 | {ebe9444a-1944-11e4-95c4-dd9a4e7158f6} |
description | Ramdisk 选项 |
ramdisksdidevice | partition=S |
ramdisksdipath | \Recovery\WindowsRE\boot.sdi |
$ramdisk = $BcdStore | Create-Object -Id $ramdiskopt -Type ([uint32]"0x30000000")
$ramdisk | Set-StringElement
([BcdLibraryElementTypes]::String_Description) "Ramdisk Options" | Out-Null
$ramdisk | Set-PartitionDeviceElement
([BcdDeviceObjectElementTypes]::Device_SdiDevice) 2 "" $sDrive | Out-Null
$ramdisk | Set-StringElement
([BcdDeviceObjectElementTypes]::String_SdiPath) "\Recovery\WindowsRE\boot.sdi" | Out-Null
Windows 引导加载程序 | |
------------------- | |
标识符 | {ebe94449-1944-11e4-95c4-dd9a4e7158f6} |
device | ramdisk=[S:]\Recovery\WindowsRE\Winre.wim,{ebe9444a-1944-11e4-95c4-dd9a4e7158f6} |
路径 | \windows\system32\winload.exe |
description | Windows 恢复环境 |
inherit | {6efb52bf-1766-41db-a6b3-0ee5eff72bd7} |
osdevice | ramdisk=[S:]\Recovery\WindowsRE\Winre.wim,{ebe9444a-1944-11e4-95c4-dd9a4e7158f6} |
systemroot | \windows |
nx | OptIn |
winpe | 是 |
custom:46000010 | 是 |
$winre = $BcdStore | Create-Object ([uint32]"0x10200003")
# Get Generated GUID
$reLoader = $winre | Get-Id
$winre | Set-FileDeviceElement
-Type ([BcdLibraryElementTypes]::Device_ApplicationDevice) -DeviceType 4 `
-AdditionalOptions $ramdiskopt -Path "\Recovery\WindowsRE\Winre.wim" -ParentDeviceType 2 `
-ParentAdditionalOptions "" -ParentPath $sDrive | Out-Null
$winre | Set-StringElement ([BcdLibraryElementTypes]::String_ApplicationPath)
"\Windows\system32\winload.exe" | Out-Null
$winre | Set-StringElement ([BcdLibraryElementTypes]::String_Description)
"Windows Recovery Environment" | Out-Null
$winre | Set-ObjectListElement ([BcdLibraryElementTypes]::ObjectList_InheritedObjects)
@($bootloadersettings) | Out-Null
$winre | Set-FileDeviceElement -Type ([BcdOSLoaderElementTypes]::Device_OSDevice)
-DeviceType 4 -AdditionalOptions $ramdiskopt `
-Path "\Recovery\WindowsRE\Winre.wim" -ParentDeviceType 2 `
-ParentAdditionalOptions "" -ParentPath $sDrive | Out-Null
$winre | Set-StringElement ([BcdOSLoaderElementTypes]::String_SystemRoot)
"\Windows" | Out-Null
$winre | Set-IntegerElement ([BcdOSLoaderElementTypes]::Integer_NxPolicy) 0 | Out-Null
$winre | Set-BooleanElement ([BcdOSLoaderElementTypes]::Boolean_WinPEMode) 1 | Out-Null
$winre | Set-BooleanElement ([uint32]"0x46000010") 1 | Out-Null
Windows 引导加载程序 | |
------------------- | |
标识符 | {ebe94448-1944-11e4-95c4-dd9a4e7158f6} |
device | partition=C |
路径 | \windows\system32\winload.exe |
description | Windows 7 |
locale | en-US |
inherit | {6efb52bf-1766-41db-a6b3-0ee5eff72bd7} |
recoverysequence | {ebe94449-1944-11e4-95c4-dd9a4e7158f6} |
recoveryenabled | 是 |
osdevice | partition=C |
systemroot | \windows |
resumeobject | {ebe94447-1944-11e4-95c4-dd9a4e7158f6} |
nx | OptIn |
$loader = $BcdStore | Create-Object ([uint32]"0x10200003")
# Get generated GUID
$osLoader = $loader | Get-Id
$loader | Set-PartitionDeviceElement
([BcdLibraryElementTypes]::Device_ApplicationDevice) 2 "" $cDrive | Out-Null
$loader | Set-StringElement
([BcdLibraryElementTypes]::String_ApplicationPath)
"\Windows\system32\winload.exe" | Out-Null
$loader | Set-StringElement
([BcdLibraryElementTypes]::String_Description) "Windows 7" | Out-Null
$loader | Set-StringElement
([BcdLibraryElementTypes]::String_PreferredLocale) "en-US" | Out-Null
$loader | Set-ObjectListElement
([BcdLibraryElementTypes]::ObjectList_InheritedObjects) @($bootloadersettings) | Out-Null
$loader | Set-ObjectListElement
([BcdLibraryElementTypes]::ObjectList_RecoverySequence) @($reLoader) | Out-Null
$loader | Set-BooleanElement
([BcdLibraryElementTypes]::Boolean_AutoRecoveryEnabled) 1 | Out-Null
$loader | Set-PartitionDeviceElement
([BcdOSLoaderElementTypes]::Device_OSDevice) 2 "" $cDrive | Out-Null
$loader | Set-StringElement
([BcdOSLoaderElementTypes]::String_SystemRoot) "\Windows" | Out-Null
$loader | Set-ObjectElement
([BcdOSLoaderElementTypes]::Object_AssociatedResumeObject) $resume | Out-Null
$loader | Set-IntegerElement
([BcdOSLoaderElementTypes]::Integer_NxPolicy) 0 | Out-Null
Windows 引导管理器 | |
-------------------- | |
标识符 | {9dea862c-5cdd-4e70-acc1-f32b344d4795} |
device | partition=S |
description | Windows 引导管理器 |
locale | en-US |
inherit | {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e} |
默认 | {ebe94448-1944-11e4-95c4-dd9a4e7158f6} |
resumeobject | {ebe94447-1944-11e4-95c4-dd9a4e7158f6} |
displayorder | {ebe94448-1944-11e4-95c4-dd9a4e7158f6} |
toolsdisplayorder | {b2721d73-1db4-4c62-bf78-c548a880142d} |
timeout | 30 |
$bootManager = $BcdStore | Create-Object -Id $bootmgr -Type ([uint32]"0x10100002")
$bootManager | Set-PartitionDeviceElement
([BcdLibraryElementTypes]::Device_ApplicationDevice) 2 "" $sDrive | Out-Null
$bootManager | Set-StringElement
([BcdLibraryElementTypes]::String_Description) "Windows Boot Manager" | Out-Null
$bootManager | Set-StringElement
([BcdLibraryElementTypes]::String_PreferredLocale) "en-US" | Out-Null
$bootManager | Set-ObjectListElement
([BcdLibraryElementTypes]::ObjectList_InheritedObjects) @($globalsettings) | Out-Null
$bootManager | Set-ObjectElement
([BcdBootMgrElementTypes]::Object_DefaultObject) $osLoader | Out-Null
$bootManager | Set-ObjectElement
([BcdOSLoaderElementTypes]::Object_AssociatedResumeObject) $resume | Out-Null
$bootManager | Set-ObjectListElement
([BcdBootMgrElementTypes]::ObjectList_DisplayOrder) @($osLoader) | Out-Null
$bootManager | Set-ObjectListElement
([BcdBootMgrElementTypes]::ObjectList_ToolsDisplayOrder) @($memdiag) | Out-Null
$bootManager | Set-IntegerElement
([BcdBootMgrElementTypes]::Integer_Timeout) 30 | Out-Null
更新 USB BCD 存储区
对于第二个演示,将一个 WinPE 文件添加到现有的 WinPE USB 中。除了添加 Windows 引导加载程序外,还有必要更新 ems(紧急管理服务)设置以显示启动菜单(如果尚未启用)。由于 BCD 存储区已有一个 Ramdisk Option,因此不需要新的;但是,有必要获取现有 Device Option 的 Id。最后,在添加新的引导加载程序后,需要更新 Windows 引导管理器的显示顺序以包含新的引导加载程序。
$storeFile = "BCD file"
$wimFile = "\sources\boot2.wim"
$bcdStore = Get-StaticBcdStore | Open-Store $storeFile
# Ramdisk Options
$devices = $bcdStore | Enumerate-Objects ([uint32]"0x30000000")
if($devices.Count -gt 1) {
Write-Host "Not prepared for this..."
return
}
else {
if(($devices | Get-Element
([BcdDeviceObjectElementTypes]::String_SdiPath)) -ne $null) {
$id = $devices | Get-Id
}
}
if([String]::IsNullOrEmpty($id)) {
Write-Host "Missing Ramdisk Option"
return
}
$winre = $BcdStore | Create-Object ([uint32]"0x10200003")
$winre | Set-FileDeviceElement
-Type ([BcdLibraryElementTypes]::Device_ApplicationDevice)
-DeviceType ([DeviceTypes]::RamdiskDevice) `
-AdditionalOptions $id -Path $wimFile -ParentDeviceType 1 `
-ParentAdditionalOptions "" -ParentPath "" | Out-Null
$winre | Set-StringElement ([BcdLibraryElementTypes]::String_ApplicationPath)
"\Windows\system32\winload.exe" | Out-Null
$winre | Set-StringElement
([BcdLibraryElementTypes]::String_Description) "An additional WinPE" | Out-Null
$winre | Set-ObjectListElement
([BcdLibraryElementTypes]::ObjectList_InheritedObjects) @($bootloadersettings) | Out-Null
$winre | Set-FileDeviceElement
-Type ([BcdOSLoaderElementTypes]::Device_OSDevice) -DeviceType 4 `
-AdditionalOptions $id -Path $wimFile -ParentDeviceType 1 `
-ParentAdditionalOptions "" -ParentPath "" | Out-Null
$winre | Set-StringElement
([BcdOSLoaderElementTypes]::String_SystemRoot) "\Windows" | Out-Null
$winre | Set-IntegerElement ([uint32]"0x250000C2") 1 | Out-Null
$winre | Set-BooleanElement
([BcdOSLoaderElementTypes]::Boolean_DetectKernelAndHal) 1 | Out-Null
$winre | Set-BooleanElement ([BcdOSLoaderElementTypes]::Boolean_WinPEMode) 1 | Out-Null
# Windows Boot Loader
$loader = $bcdStore | Enumerate-Objects ([uint32]"0x10200003")
$values = @()
$loader | % {
$values += ($_ | Get-Id)
# update ems
$_ | Set-BooleanElement
([BcdOSLoaderElementTypes]::Boolean_EmsEnabled) 1 | Out-Null
}
# enable ems
$BcdStore | Open-Object $emssettings |
Set-BooleanElement ([BcdLibraryElementTypes]::Boolean_EmsEnabled) 1 | Out-Null
$bcdStore | Open-Object $bootmgr | Set-ObjectListElement
-Type ([BcdBootMgrElementTypes]::ObjectList_DisplayOrder) -Ids $values
*引导加载程序和引导管理器出现的 Boolean_EmsEnabled
不相同。
仅为好玩——构建 BCD 模板
最后一个演示将重新创建位于 system32\config 的 BCD-Template。这将展示一些标准 BCD 存储区中未定义的 BCD 对象。
一些重复的操作已简化——例如,使用 Set-InheritedObjects
函数来包装 Set-ObjectListElement
([BcdLibraryElementTypes]::ObjectList_InheritedObjects)
。此外,混合使用基本和详细的 bcdedit
输出,以提供更准确的演示代码结果。
EMS 设置 | |
------------ | |
标识符 | {emssettings} |
bootems | 是 |
$BcdStore | Create-Object -Id $emssettings -Type ([uint32]"0x20100000") | `
Set-BooleanElement ([BcdLibraryElementTypes]::Boolean_EmsEnabled) 1 | Out-Null
调试器设置 | |
----------------- | |
标识符 | {dbgsettings} |
debugtype | 串口 |
debugport | 1 |
baudrate | 115200 |
$debugger = $BcdStore | Create-Object -Id $dbgsettings -Type ([uint32]"0x20100000")
$debugger | Set-IntegerElement ([BcdLibraryElementTypes]::Integer_DebuggerType) 0 | Out-Null
$debugger | Set-IntegerElement
([BcdLibraryElementTypes]::Integer_SerialDebuggerPort) 1 | Out-Null
$debugger | Set-IntegerElement
([BcdLibraryElementTypes]::Integer_SerialDebuggerBaudRate) 115200 | Out-Null
RAM 缺陷 | |
----------- | |
标识符 | {badmemory} |
$BcdStore | Create-Object -Id $badmemory -Type ([uint32]"0x20100000") | Out-Null
全局设置 | |
--------------- | |
标识符 | {globalsettings} |
inherit | {dbgsettings} |
{emssettings} | |
{badmemory} |
$global = $BcdStore | Create-Object -Id $globalsettings -Type ([uint32]"0x20100000") | `
Set-InheritedObjects @($dbgsettings,$emssettings,$badmemory) | Out-Null
恢复加载程序设置 | |
---------------------- | |
标识符 | {resumeloadersettings} |
inherit | {globalsettings} |
$BcdStore | Create-Object -Id $resumeloadersettings -Type ([uint32]"0x20200004") | `
Set-InheritedObjects -Value @($globalsettings) | Out-Null
Windows 传统操作系统加载程序 | |
------------------------ | |
标识符 | {ntldr} |
路径 | \ntldr |
custom:45000001 | 1 |
custom:47000005 | 301989892 |
6 |
$legacy = $BcdStore | Create-Object -Id $ntldr -Type ([uint32]"0x10300006")
$legacy | Set-ApplicationPath "\ntldr" | Out-Null
$legacy | Set-IntegerElement ([uint32]"0x45000001") 1 | Out-Null
$legacy | Set-IntegerListElement ([uint32]"0x47000005")
@(([uint32]"0x12000004"),6) | Out-Null
Hypervisor 设置 | |
------------------- | |
标识符 | {hypervisorsettings} |
hypervisordebugtype | 串口 |
hypervisordebugport | 1 |
hypervisorbaudrate | 115200 |
$hypervisor = $BcdStore | Create-Object -Id $hypervisorsettings -Type ([uint32]"0x20200003")
$hypervisor | Set-IntegerElement
([BcdOSLoaderElementTypes]::Integer_HypervisorDebuggerType) 0 | Out-Null
$hypervisor | Set-IntegerElement
([BcdOSLoaderElementTypes]::Integer_HypervisorDebuggerPortNumber) 1 | Out-Null
$hypervisor | Set-IntegerElement
([BcdOSLoaderElementTypes]::Integer_HypervisorDebuggerBaudrate) 115200 | Out-Null
引导加载程序设置 | |
-------------------- | |
标识符 | {bootloadersettings} |
inherit | {globalsettings} |
{hypervisorsettings} |
$BcdStore | Create-Object -Id $bootloadersettings -Type ([uint32]"0x20200003") | `
Set-InheritedObjects @($globalsettings,$hypervisorsettings) | Out-Null
Windows 内存测试程序 | |
--------------------- | |
标识符 | {memdiag} |
路径 | \boot\memtest.exe |
locale | en-US |
inherit | {globalsettings} |
badmemoryaccess | 是 |
custom:45000001 | 1 |
custom:47000005 | 301989892 |
2 |
$memorytester = $BcdStore | Create-Object -Id $memdiag -Type ([uint32]"0x10200005")
$memorytester | Set-ApplicationPath "\boot\memtest.exe" | Out-Null
$memorytester | Set-PreferredLocale "en-US" | Out-Null
$memorytester | Set-InheritedObjects @($globalsettings) | Out-Null
$memorytester | Set-BooleanElement
([BcdLibraryElementTypes]::Boolean_AllowBadMemoryAccess) 1 | Out-Null
$memorytester | Set-IntegerElement ([uint32]"0x45000001") 1 | Out-Null
$memorytester | Set-IntegerListElement
([uint32]"0x47000005") @(([uint32]"0x12000004"),2) | Out-Null
从休眠中恢复 | |
--------------------- | |
标识符 | {0c334284-9a41-4de1-99b3-a7e87e8ff07e} |
description | Windows 恢复应用程序 |
locale | en-US |
inherit | {resumeloadersettings} |
filepath | \hiberfil.sys |
custom:42000002 | \system32\winresume.efi |
custom:45000001 | 2 |
custom:46000004 | 是 |
$hib2 = $BcdStore | Create-Object
-Id "{0c334284-9a41-4de1-99b3-a7e87e8ff07e}" -Type ([uint32]"0x10200004")
$hib2 | Set-Description "Windows Resume Application" | Out-Null
$hib2 | Set-PreferredLocale "en-US" | Out-Null
$hib2 | Set-InheritedObjects @($resumeloadersettings) | Out-Null
# String_HiberFilePath
$hib2 | Set-StringElement ([BcdOSLoaderElementTypes]::String_SystemRoot)
"\hiberfil.sys" | Out-Null
$hib2 | Set-StringElement ([uint32]"0x42000002") "\system32\winresume.efi" | Out-Null
$hib2 | Set-IntegerElement ([uint32]"0x45000001") 2 | Out-Null
$hib2 | Set-BooleanElement ([uint32]"0x46000004") 1 | Out-Null
从休眠中恢复 | |
--------------------- | |
标识符 | {98b02a23-0674-4ce7-bdad-e0a15a8ff97b} |
description | Windows 恢复应用程序 |
locale | en-US |
inherit | {resumeloadersettings} |
filepath | \hiberfil.sys |
custom:42000002 | \system32\winresume.exe |
custom:45000001 | 2 |
custom:46000004 | 是 |
$hib1 = $BcdStore | Create-Object
-Id "{98b02a23-0674-4ce7-bdad-e0a15a8ff97b}" -Type ([uint32]"0x10200004")
$hib1 | Set-Description "Windows Resume Application" | Out-Null
$hib1 | Set-PreferredLocale "en-US" | Out-Null
$hib1 | Set-InheritedObjects @($resumeloadersettings) | Out-Null
$hib1 | Set-StringElement ([BcdOSLoaderElementTypes]::String_SystemRoot)
"\hiberfil.sys" | Out-Null
$hib1 | Set-StringElement ([uint32]"0x42000002") "\system32\winresume.exe" | Out-Null
$hib1 | Set-IntegerElement ([uint32]"0x45000001") 2 | Out-Null
$hib1 | Set-BooleanElement ([uint32]"0x46000004") 1 | Out-Null
OS 目标模板 | |
------------------ | |
标识符 | {a1943bbc-ea85-487c-97c7-c9ede908a38a} |
locale | en-US |
inherit | {6efb52bf-1766-41db-a6b3-0ee5eff72bd7} |
systemroot | \windows |
resumeobject | {98b02a23-0674-4ce7-bdad-e0a15a8ff97b} |
nx | OptIn |
detecthal | 是 |
custom:42000002 | \system32\winload.exe |
custom:45000001 | 2 |
custom:47000005 | 301989892 |
3 |
$template2 = $BcdStore | Create-Object
-Id "{a1943bbc-ea85-487c-97c7-c9ede908a38a}" -Type ([uint32]"0x10200003")
$template2 | Set-PreferredLocale "en-US" | Out-Null
$template2 | Set-InheritedObjects @($bootloadersettings) | Out-Null
$template2 | Set-StringElement ([BcdOSLoaderElementTypes]::String_SystemRoot)
"\windows" | Out-Null
$template2 | Set-ObjectElement ([BcdOSLoaderElementTypes]::Object_AssociatedResumeObject)
"{98b02a23-0674-4ce7-bdad-e0a15a8ff97b}" | Out-Null
$template2 | Set-IntegerElement ([BcdOSLoaderElementTypes]::Integer_NxPolicy) 0 | Out-Null
$template2 | Set-BooleanElement ([BcdOSLoaderElementTypes]::Boolean_DetectKernelAndHal)
1 | Out-Null
$template2 | Set-BooleanElement ([BcdOSLoaderElementTypes]::Boolean_WinPEMode) 1 | Out-Null
$template2 | Set-StringElement ([uint32]"0x42000002") "\system32\winload.exe" | Out-Null
$template2 | Set-IntegerElement ([uint32]"0x45000001") 2 | Out-Null
$template2 | Set-IntegerListElement
([uint32]"0x47000005") @(([uint32]"0x12000004"),3) | Out-Null
OS 目标模板 | |
------------------ | |
标识符 | {b012b84d-c47c-4ed5-b722-c0c42163e569} |
locale | en-US |
inherit | {6efb52bf-1766-41db-a6b3-0ee5eff72bd7} |
systemroot | \windows |
resumeobject | {0c334284-9a41-4de1-99b3-a7e87e8ff07e} |
nx | OptIn |
detecthal | 是 |
custom:42000002 | \system32\winload.efi |
custom:45000001 | 2 |
custom:47000005 | 301989892 |
3 |
$template1 = $BcdStore | Create-Object
-Id "{b012b84d-c47c-4ed5-b722-c0c42163e569}" -Type ([uint32]"0x10200003")
$template1 | Set-PreferredLocale "en-US" | Out-Null
$template1 | Set-InheritedObjects @($bootloadersettings) | Out-Null
$template1 | Set-StringElement ([BcdOSLoaderElementTypes]::String_SystemRoot)
"\windows" | Out-Null
$template1 | Set-ObjectElement ([BcdOSLoaderElementTypes]::Object_AssociatedResumeObject)
"{0c334284-9a41-4de1-99b3-a7e87e8ff07e}" | Out-Null
$template1 | Set-IntegerElement ([BcdOSLoaderElementTypes]::Integer_NxPolicy) 0 | Out-Null
$template1 | Set-BooleanElement ([BcdOSLoaderElementTypes]::Boolean_DetectKernelAndHal)
1 | Out-Null
$template1 | Set-BooleanElement ([BcdOSLoaderElementTypes]::Boolean_WinPEMode) 1 | Out-Null
$template1 | Set-StringElement ([uint32]"0x42000002") "\system32\winload.efi" | Out-Null
$template1 | Set-IntegerElement ([uint32]"0x45000001") 2 | Out-Null
$template1 | Set-IntegerListElement
([uint32]"0x47000005") @(([uint32]"0x12000004"),3) | Out-Null
Windows 安装程序 | |
------------- | |
标识符 | {default} |
locale | en-US |
inherit | {bootloadersettings} |
systemroot | \windows |
nx | OptOut |
detecthal | 是 |
winpe | 是 |
custom:42000002 | \system32\winload.exe |
custom:42000003 | \boot.wim |
custom:45000001 | 2 |
custom:47000005 | 301989892 |
1 |
$setup1 = $BcdStore | Create-Object -Id "{cbd971bf-b7b8-4885-951a-fa03044f5d71}"
-Type ([uint32]"0x10200003")
$setup1 | Set-PreferredLocale "en-US" | Out-Null
$setup1 | Set-InheritedObjects @($bootloadersettings) | Out-Null
$setup1 | Set-StringElement ([BcdOSLoaderElementTypes]::String_SystemRoot)
"\windows" | Out-Null
$setup1 | Set-IntegerElement ([BcdOSLoaderElementTypes]::Integer_NxPolicy) 1 | Out-Null
$setup1 | Set-BooleanElement
([BcdOSLoaderElementTypes]::Boolean_DetectKernelAndHal) 1 | Out-Null
$setup1 | Set-BooleanElement ([BcdOSLoaderElementTypes]::Boolean_WinPEMode) 1 | Out-Null
$setup1 | Set-StringElement ([uint32]"0x42000002") "\system32\winload.exe" | Out-Null
$setup1 | Set-StringElement ([uint32]"0x42000003") "\boot.wim" | Out-Null
$setup1 | Set-IntegerElement ([uint32]"0x45000001") 2 | Out-Null
$setup1 | Set-IntegerListElement
([uint32]"0x47000005") @(([uint32]"0x12000004"),1) | Out-Null
Windows 安装程序 | |
------------- | |
标识符 | {7254a080-1510-4e85-ac0f-e7fb3d444736} |
locale | en-US |
inherit | {bootloadersettings} |
systemroot | \windows |
nx | OptOut |
detecthal | 是 |
winpe | 是 |
custom:42000002 | \system32\winload.efi |
custom:42000003 | \boot.wim |
custom:45000001 | 2 |
custom:47000005 | 301989892 |
1 |
$setup2 = $BcdStore | Create-Object
-Id "{7254a080-1510-4e85-ac0f-e7fb3d444736}" -Type ([uint32]"0x10200003")
$setup2 | Set-PreferredLocale "en-US" | Out-Null
$setup2 | Set-InheritedObjects @($bootloadersettings) | Out-Null
$setup2 | Set-StringElement
([BcdOSLoaderElementTypes]::String_SystemRoot) "\windows" | Out-Null
$setup2 | Set-IntegerElement ([BcdOSLoaderElementTypes]::Integer_NxPolicy) 1 | Out-Null
$setup2 | Set-BooleanElement
([BcdOSLoaderElementTypes]::Boolean_DetectKernelAndHal) 1 | Out-Null
$setup2 | Set-BooleanElement ([BcdOSLoaderElementTypes]::Boolean_WinPEMode) 1 | Out-Null
$setup2 | Set-StringElement ([uint32]"0x42000002") "\system32\winload.efi" | Out-Null
$setup2 | Set-StringElement ([uint32]"0x42000003") "\boot.wim" | Out-Null
$setup2 | Set-IntegerElement ([uint32]"0x45000001") 2 | Out-Null
$setup2 | Set-IntegerListElement
([uint32]"0x47000005") @(([uint32]"0x12000004"),1) | Out-Null
Windows 引导管理器 | |
-------------------- | |
标识符 | {bootmgr} |
路径 | \EFI\Microsoft\Boot\bootmgfw.efi |
description | Windows 引导管理器 |
locale | en-US |
inherit | {globalsettings} |
默认 | {default} |
timeout | 30 |
custom:45000001 | 1 |
$bootManager = $BcdStore | Create-Object -Id $bootmgr -Type ([uint32]"0x10100002")
$bootManager | Set-ApplicationPath "\EFI\Microsoft\Boot\bootmgfw.efi" | Out-Null
$bootManager | Set-Description "Windows Boot Manager" | Out-Null
$bootManager | Set-PreferredLocale "en-US" | Out-Null
$bootManager | Set-InheritedObjects @($globalsettings) | Out-Null
$bootManager | Set-ObjectElement ([BcdBootMgrElementTypes]::Object_DefaultObject)
"{cbd971bf-b7b8-4885-951a-fa03044f5d71}" | Out-Null
$bootManager | Set-IntegerElement ([BcdBootMgrElementTypes]::Integer_Timeout) 30 | Out-Null
$bootManager | Set-IntegerElement ([uint32]"0x45000001") 1 | Out-Null
PowerShell BCD 代码
以下代码可以保存到文件中并使用以下命令链接
. ("FileName.ps1")
此代码不完整。尽管 WMI 方法已定义,但仍可为对象类型添加新的枚举器,并且许多从 Microsoft 复制的枚举器仍可能不正确。此代码只是一个基础。
try {
$check = ($deviceMethods -eq [Kernel32.NativeMethods])
}
catch {
$deviceMethods = Add-Type -MemberDefinition @'
[DllImport("Kernel32.dll",
EntryPoint = "QueryDosDeviceA", CharSet = CharSet.Ansi, SetLastError=true)]
public static extern int QueryDosDevice
(string lpDeviceName, System.Text.StringBuilder lpTargetPath, int ucchMax);
'@ -Name NativeMethods -Namespace Kernel32 -PassThru
}
function Get-DosDevice {
Param([Parameter(Mandatory=$true, Position=0)]$DriveLetter)
$sb = New-Object System.Text.StringBuilder(30)
$ret = $deviceMethods::QueryDosDevice($DriveLetter, $sb, 30)
if($ret -gt 0) {
$sb.ToString()
}
}
function Has-Role {
param([Security.Principal.WindowsBuiltInRole]$Role =
[Security.Principal.WindowsBuiltInRole]::Administrator)
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal $identity
return $principal.IsInRole($Role)
}
function Get-StaticBcdStore {
$SWbemLocator = New-Object -ComObject WbemScripting.SWbemLocator
$wmi = $SWbemLocator.ConnectServer(".","root\wmi")
$wmi.Get("BcdStore")
}
function Set-InheritedObjects {
Param([Parameter(Position=0)]$Value, [Parameter(ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Set-ObjectListElement
-Type ([BcdLibraryElementTypes]::ObjectList_InheritedObjects) $Value
}
function Set-ApplicationPath {
Param([Parameter(Position=0)][string]$Value, [Parameter(ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Set-StringElement ([BcdLibraryElementTypes]::String_ApplicationPath) $Value
}
function Set-Description {
Param([Parameter(Position=0)][string]$Value, [Parameter(ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Set-StringElement ([BcdLibraryElementTypes]::String_Description) $Value
}
function Set-PreferredLocale {
Param([Parameter(Position=0)][string]$Value, [Parameter(ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Set-StringElement ([BcdLibraryElementTypes]::String_PreferredLocale) $Value
}
##########################
### COM Helper ###
##########################
function New-InParameter {
Param([Parameter(Position=0)]$Method, [Parameter(ValueFromPipeLine=$true)]$Object)
$Object.Methods_.Item($Method).InParameters.SpawnInstance_()
}
function Get-PropertyValue {
Param([Parameter(Position=0)]$Property, [Parameter(ValueFromPipeLine=$true)]$Object)
$Object.Properties_.Item($Property).Value
}
function Set-PropertyValue {
Param([Parameter(Position=0)]$Property,
[Parameter(Position=1)]$Value, [Parameter(ValueFromPipeLine=$true)]$Object)
$Object.Properties_.Item($Property).Value=$Value
}
# 20201101 Work Around Posted for exception:
Unable to cast object of type 'System.UInt32' to type 'System.String'
function Invoke-Method {
Param([Parameter(Position=0)]$Method,
[Parameter(Position=1)]$ParameterNames, [Parameter(Position=2)]$ParameterValues,
[Parameter(ValueFromPipeLine=$true)]$Object)
if($ParameterNames -eq $null -or $ParameterValues -eq $null) {
# If the method has required parameters: "The remote procedure call failed."
$Object.ExecMethod_($Method)
}
else {
$in = $Object.Methods_.Item($Method).InParameters.SpawnInstance_()
if($ParameterNames.GetType() -eq [System.String]) {
$prop = $in.Properties_.Item($ParameterNames)
$prop.GetType().InvokeMember("Value",
[System.Reflection.BindingFlags]::SetProperty,$null,$prop,@($ParameterValues))
}
else {
for($i = 0; $i -lt $ParameterNames.LongLength; $i++) {
if($ParameterValues[$i] -ne $null) {
$prop = $in.Properties_.Item($ParameterNames[$i])
if($ParameterValues[$i] -is [array]) {
$prop.GetType().InvokeMember("Value",
[System.Reflection.BindingFlags]::SetProperty,
$null,$prop,@(,$ParameterValues[$i]))
} else {
$prop.GetType().InvokeMember("Value",
[System.Reflection.BindingFlags]::SetProperty,
$null,$prop,@($ParameterValues[$i]))
}
}
}
}
$Object.ExecMethod_($Method, $in)
}
}
function Release-ComObject {
Param([Parameter(Position=0, ValueFromPipeLine=$true)]$ComObject)
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($ComObject)
}
###########################
### Known GUIDs ###
###########################
# BCD-Template (Windows 7 Pro)
$bootmgr = "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"
$resumeloadersettings = "{1afa9c49-16ab-4a5c-901b-212802da9460}"
$memdiag = "{b2721d73-1db4-4c62-bf78-c548a880142d}"
$ntldr = "{466f5a88-0af2-4f76-9038-095b170dc21c}"
$dbgsettings = "{4636856e-540f-4170-a130-a84776f4c654}"
$emssettings = "{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}"
$bootloadersettings = "{6efb52bf-1766-41db-a6b3-0ee5eff72bd7}"
$hypervisorsettings = "{7ff607e0-4395-11db-b0de-0800200c9a66}"
$globalsettings = "{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}"
$badmemory = "{5189b25c-5558-4bf2-bca4-289b11bd29e2}"
# BCD.doc - 2006
$fwbootmgr = "{a5a30fa2-3d06-4e9f-b5f4-a01df9d1fcba}"
$resumeapp = "{147aa509-0358-4473-b83b-d950dda00615}"
$ramdiskopt = "{AE5534E0-A924-466C-B836-758539A3EE3A}"
############################
### Object Types ###
############################
if(!(([System.Management.Automation.PSTypeName]"BcdBootMgrElementTypes").Type)) {
Add-Type -TypeDefinition @'
public enum BcdBootMgrElementTypes : uint
{
ObjectList_DisplayOrder = 0x24000001,
ObjectList_BootSequence = 0x24000002,
Object_DefaultObject = 0x23000003,
Integer_Timeout = 0x25000004,
Boolean_AttemptResume = 0x26000005,
Object_ResumeObject = 0x23000006,
ObjectList_ToolsDisplayOrder = 0x24000010,
Boolean_DisplayBootMenu = 0x26000020,
Boolean_NoErrorDisplay = 0x26000021,
Device_BcdDevice = 0x21000022,
String_BcdFilePath = 0x22000023,
Boolean_ProcessCustomActionsFirst = 0x26000028,
IntegerList_CustomActionsList = 0x27000030,
Boolean_PersistBootSequence = 0x26000031
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdDeviceObjectElementTypes").Type)) {
Add-Type -TypeDefinition @'
public enum BcdDeviceObjectElementTypes : uint
{
Integer_RamdiskImageOffset = 0x35000001,
Integer_TftpClientPort = 0x35000002,
Device_SdiDevice = 0x31000003,
String_SdiPath = 0x32000004,
Integer_RamdiskImageLength = 0x35000005,
Boolean_RamdiskExportAsCd = 0x36000006,
Integer_RamdiskTftpBlockSize = 0x36000007,
Integer_RamdiskTftpWindowSize = 0x36000008,
Boolean_RamdiskMulticastEnabled = 0x36000009,
Boolean_RamdiskMulticastTftpFallback = 0x3600000A,
Boolean_RamdiskTftpVarWindow = 0x3600000B
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdLibrary_DebuggerType").Type)) {
Add-Type -TypeDefinition @'
public enum BcdLibrary_DebuggerType
{
DebuggerSerial = 0,
Debugger1394 = 1,
DebuggerUsb = 2,
DebuggerNet = 3
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdLibrary_SafeBoot").Type)) {
Add-Type -TypeDefinition @'
public enum BcdLibrary_SafeBoot
{
SafemodeMinimal = 0,
SafemodeNetwork = 1,
SafemodeDsRepair = 2
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdLibraryElementTypes").Type)) {
Add-Type -TypeDefinition @'
public enum BcdLibraryElementTypes : uint
{
Device_ApplicationDevice = 0x11000001,
String_ApplicationPath = 0x12000002,
String_Description = 0x12000004,
String_PreferredLocale = 0x12000005,
ObjectList_InheritedObjects = 0x14000006,
Integer_TruncatePhysicalMemory = 0x15000007,
ObjectList_RecoverySequence = 0x14000008,
Boolean_AutoRecoveryEnabled = 0x16000009,
IntegerList_BadMemoryList = 0x1700000a,
Boolean_AllowBadMemoryAccess = 0x1600000b,
Integer_FirstMegabytePolicy = 0x1500000c,
Integer_RelocatePhysicalMemory = 0x1500000D,
Integer_AvoidLowPhysicalMemory = 0x1500000E,
Boolean_DebuggerEnabled = 0x16000010,
Integer_DebuggerType = 0x15000011,
Integer_SerialDebuggerPortAddress = 0x15000012,
Integer_SerialDebuggerPort = 0x15000013,
Integer_SerialDebuggerBaudRate = 0x15000014,
Integer_1394DebuggerChannel = 0x15000015,
String_UsbDebuggerTargetName = 0x12000016,
Boolean_DebuggerIgnoreUsermodeExceptions = 0x16000017,
Integer_DebuggerStartPolicy = 0x15000018,
String_DebuggerBusParameters = 0x12000019,
Integer_DebuggerNetHostIP = 0x1500001A,
Integer_DebuggerNetPort = 0x1500001B,
Boolean_DebuggerNetDhcp = 0x1600001C,
String_DebuggerNetKey = 0x1200001D,
Boolean_EmsEnabled = 0x16000020,
Integer_EmsPort = 0x15000022,
Integer_EmsBaudRate = 0x15000023,
String_LoadOptionsString = 0x12000030,
Boolean_DisplayAdvancedOptions = 0x16000040,
Boolean_DisplayOptionsEdit = 0x16000041,
Device_BsdLogDevice = 0x11000043,
String_BsdLogPath = 0x12000044,
Boolean_GraphicsModeDisabled = 0x16000046,
Integer_ConfigAccessPolicy = 0x15000047,
Boolean_DisableIntegrityChecks = 0x16000048,
Boolean_AllowPrereleaseSignatures = 0x16000049,
String_FontPath = 0x1200004A,
Integer_SiPolicy = 0x1500004B,
Integer_FveBandId = 0x1500004C,
Boolean_ConsoleExtendedInput = 0x16000050,
Integer_GraphicsResolution = 0x15000052,
Boolean_RestartOnFailure = 0x16000053,
Boolean_GraphicsForceHighestMode = 0x16000054,
Boolean_IsolatedExecutionContext = 0x16000060,
Boolean_BootUxDisable = 0x1600006C,
Boolean_BootShutdownDisabled = 0x16000074,
IntegerList_AllowedInMemorySettings = 0x17000077,
Boolean_ForceFipsCrypto = 0x16000079
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdMemDiagElementTypes").Type)) {
Add-Type -TypeDefinition @'
public enum BcdMemDiagElementTypes : uint
{
Integer_PassCount = 0x25000001,
Integer_FailureCount = 0x25000003
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdOSLoader_NxPolicy").Type)) {
Add-Type -TypeDefinition @'
public enum BcdOSLoader_NxPolicy
{
NxPolicyOptIn = 0,
NxPolicyOptOut = 1,
NxPolicyAlwaysOff = 2,
NxPolicyAlwaysOn = 3
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdOSLoader_PAEPolicy").Type)) {
Add-Type -TypeDefinition @'
public enum BcdOSLoader_PAEPolicy
{
PaePolicyDefault = 0,
PaePolicyForceEnable = 1,
PaePolicyForceDisable = 2
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdOSLoaderElementTypes").Type)) {
Add-Type -TypeDefinition @'
public enum BcdOSLoaderElementTypes : uint
{
Device_OSDevice = 0x21000001,
String_SystemRoot = 0x22000002,
Object_AssociatedResumeObject = 0x23000003,
Boolean_DetectKernelAndHal = 0x26000010,
String_KernelPath = 0x22000011,
String_HalPath = 0x22000012,
String_DbgTransportPath = 0x22000013,
Integer_NxPolicy = 0x25000020,
Integer_PAEPolicy = 0x25000021,
Boolean_WinPEMode = 0x26000022,
Boolean_DisableCrashAutoReboot = 0x26000024,
Boolean_UseLastGoodSettings = 0x26000025,
Boolean_AllowPrereleaseSignatures = 0x26000027,
Boolean_NoLowMemory = 0x26000030,
Integer_RemoveMemory = 0x25000031,
Integer_IncreaseUserVa = 0x25000032,
Boolean_UseVgaDriver = 0x26000040,
Boolean_DisableBootDisplay = 0x26000041,
Boolean_DisableVesaBios = 0x26000042,
Boolean_DisableVgaMode = 0x26000043,
Integer_ClusterModeAddressing = 0x25000050,
Boolean_UsePhysicalDestination = 0x26000051,
Integer_RestrictApicCluster = 0x25000052,
Boolean_UseLegacyApicMode = 0x26000054,
Integer_X2ApicPolicy = 0x25000055,
Boolean_UseBootProcessorOnly = 0x26000060,
Integer_NumberOfProcessors = 0x25000061,
Boolean_ForceMaximumProcessors = 0x26000062,
Boolean_ProcessorConfigurationFlags = 0x25000063,
Boolean_MaximizeGroupsCreated = 0x26000064,
Boolean_ForceGroupAwareness = 0x26000065,
Integer_GroupSize = 0x25000066,
Integer_UseFirmwarePciSettings = 0x26000070,
Integer_MsiPolicy = 0x25000071,
Integer_SafeBoot = 0x25000080,
Boolean_SafeBootAlternateShell = 0x26000081,
Boolean_BootLogInitialization = 0x26000090,
Boolean_VerboseObjectLoadMode = 0x26000091,
Boolean_KernelDebuggerEnabled = 0x260000a0,
Boolean_DebuggerHalBreakpoint = 0x260000a1,
Boolean_UsePlatformClock = 0x260000A2,
Boolean_ForceLegacyPlatform = 0x260000A3,
Integer_TscSyncPolicy = 0x250000A6,
Boolean_EmsEnabled = 0x260000b0,
Integer_DriverLoadFailurePolicy = 0x250000c1,
Integer_BootMenuPolicy = 0x250000C2,
Boolean_AdvancedOptionsOneTime = 0x260000C3,
Integer_BootStatusPolicy = 0x250000E0,
Boolean_DisableElamDrivers = 0x260000E1,
Integer_HypervisorLaunchType = 0x250000F0,
Boolean_HypervisorDebuggerEnabled = 0x260000F2,
Integer_HypervisorDebuggerType = 0x250000F3,
Integer_HypervisorDebuggerPortNumber = 0x250000F4,
Integer_HypervisorDebuggerBaudrate = 0x250000F5,
Integer_HypervisorDebugger1394Channel = 0x250000F6,
Integer_BootUxPolicy = 0x250000F7,
String_HypervisorDebuggerBusParams = 0x220000F9,
Integer_HypervisorNumProc = 0x250000FA,
Integer_HypervisorRootProcPerNode = 0x250000FB,
Boolean_HypervisorUseLargeVTlb = 0x260000FC,
Integer_HypervisorDebuggerNetHostIp = 0x250000FD,
Integer_HypervisorDebuggerNetHostPort = 0x250000FE,
Integer_TpmBootEntropyPolicy = 0x25000100,
String_HypervisorDebuggerNetKey = 0x22000110,
Boolean_HypervisorDebuggerNetDhcp = 0x26000114,
Integer_HypervisorIommuPolicy = 0x25000115,
Integer_XSaveDisable = 0x2500012b
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"BcdResumeElementTypes").Type)) {
Add-Type -TypeDefinition @'
public enum BcdResumeElementTypes : uint
{
Reserved1 = 0x21000001,
Reserved2 = 0x22000002,
Boolean_UseCustomSettings = 0x26000003,
Device_AssociatedOsDevice = 0x21000005,
Boolean_DebugOptionEnabled = 0x26000006,
Integer_BootMenuPolicy = 0x25000008
}
'@
}
if(!(([System.Management.Automation.PSTypeName]"ApplicationObjectTypes").Type)) {
Add-Type -TypeDefinition @'
public enum ApplicationObjectTypes : uint
{
fwbootmgr = 0x10100001,
bootmgr = 0x10100002,
osloader = 0x10200003,
resume = 0x10200004,
memdiag = 0x10200005,
ntldr = 0x10300006,
bootsector = 0x10400008,
startup = 0x10400009
}
'@
}
#########################
### BcdObject ###
#########################
function Enumerate-ElementTypes {
Param([Parameter(Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Invoke-Method "EnumerateElementTypes" | Get-PropertyValue "Types"
}
function Enumerate-Elements {
Param([Parameter(Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Invoke-Method "EnumerateElements" | Get-PropertyValue "Elements"
}
function Get-Element {
Param([Parameter(Position=0)][uint32]$Type,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "GetElement"
"Type" $Type | Get-PropertyValue "Element"
}
function Get-ElementWithFlags {
Param([Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][int]$Flags,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "GetElementWithFlags"
"Id","Flags" $Id,$Flags | Get-PropertyValue "Element"
}
function Set-DeviceElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][int]$DeviceType,
[Parameter(Position=2)][string]$AdditionalOptions,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$parameterNames = "Type","DeviceType","AdditionalOptions"
$parameterValues = $Type,$DeviceType,$AdditionalOptions
$BcdObject | Invoke-Method "SetDeviceElement"
$parameterNames $parameterValues | Get-PropertyValue "ReturnValue"
}
function Set-PartitionDeviceElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][int]$DeviceType,
[Parameter(Position=2)][string]$AdditionalOptions,
[Parameter(Position=3)][string]$Path,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$parameterNames = "Type","DeviceType","AdditionalOptions","Path"
$parameterValues = $Type,$DeviceType,$AdditionalOptions,$Path
$BcdObject | Invoke-Method "SetPartitionDeviceElement"
$parameterNames $parameterValues | Get-PropertyValue "ReturnValue"
}
function Set-PartitionDeviceElementWithFlags {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][int]$DeviceType,
[Parameter(Position=2)][string]$AdditionalOptions,
[Parameter(Position=3)][string]$Path,
[Parameter(Position=4)][int]$Flags,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$parameterNames = "Type",
"DeviceType","AdditionalOptions","Path","Flags"
$parameterValues = $Type,$DeviceType,$AdditionalOptions,$Path,$Flags
$BcdObject | Invoke-Method "SetPartitionDeviceElementWithFlags"
$parameterNames $parameterValues | Get-PropertyValue "ReturnValue"
}
function Set-FileDeviceElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][int]$DeviceType,
[Parameter(Position=2)][string]$AdditionalOptions,
[Parameter(Position=3)][string]$Path,
[Parameter(Position=4)][uint32]$ParentDeviceType,
[Parameter(Position=5)][string]$ParentAdditionalOptions,
[Parameter(Position=6)][string]$ParentPath,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$parameterNames = "Type","DeviceType",
"AdditionalOptions","Path","ParentDeviceType",
"ParentAdditionalOptions","ParentPath"
$parameterValues = $Type,$DeviceType,$AdditionalOptions,$Path,
$ParentDeviceType,$ParentAdditionalOptions,$ParentPath
$BcdObject | Invoke-Method "SetFileDeviceElement"
$parameterNames $parameterValues | Get-PropertyValue "ReturnValue"
}
function Set-QualifiedPartitionDeviceElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][int]$PartitionStyle,
[Parameter(Position=2)][string]$DiskSignature,
[Parameter(Position=3)][string]$PartitionIdentifier,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$parameterNames = "Type","PartitionStyle",
"DiskSignature","PartitionIdentifier"
$parameterValues = $Type,$PartitionStyle,$DiskSignature,$PartitionIdentifier
$BcdObject | Invoke-Method "SetQualifiedPartitionDeviceElement"
$parameterNames $parameterValues | Get-PropertyValue "ReturnValue"
}
function Set-VhdDeviceElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][string]$Path,
[Parameter(Position=2)][uint32]$ParentDeviceType,
[Parameter(Position=3)][string]$ParentAdditionalOptions,
[Parameter(Position=4)][string]$ParentPath,
[Parameter(Position=5)][uint32]$CustomLocate,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$parameterNames = "Type","Path","ParentDeviceType",
"ParentAdditionalOptions","ParentPath","CustomLocate"
$parameterValues = $Type,$Path,$ParentDeviceType,
$ParentAdditionalOptions,$ParentPath,$CustomLocate
$BcdObject | Invoke-Method "SetVhdDeviceElement"
$parameterNames $parameterValues | Get-PropertyValue "ReturnValue"
}
function Set-StringElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][string]$String,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetStringElement"
"Type","String" $Type,$String | Get-PropertyValue "ReturnValue"
}
function Set-ObjectElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][string]$Id,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetObjectElement"
"Type","Id" $Type,$Id | Get-PropertyValue "ReturnValue"
}
function Set-ObjectListElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)]$Ids,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetObjectListElement"
"Type","Ids" $Type,$Ids | Get-PropertyValue "ReturnValue"
}
function Set-IntegerElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)]$Integer,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetIntegerElement" "Type",
"Integer" $Type,$Integer | Get-PropertyValue "ReturnValue"
}
function Set-IntegerListElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)]$Integers,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetIntegerListElement" "Type",
"Integers" $Type,$Integers | Get-PropertyValue "ReturnValue"
}
function Set-BooleanElement {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][bool]$Boolean,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "SetBooleanElement" "Type",
"Boolean" $Type,$Boolean | Get-PropertyValue "ReturnValue"
}
function Delete-Element {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(ValueFromPipeLine=$true)]$BcdObject
)
$BcdObject | Invoke-Method "DeleteElement"
"Type" $Type | Get-PropertyValue "ReturnValue"
}
########################
### BcdStore ###
########################
function Get-FilePath {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdStore)
$BcdStore | Get-PropertyValue "FilePath"
}
function Open-Store {
Param(
[Parameter(Position=0)][string]$File="",
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "OpenStore"
"File" $File | Get-PropertyValue "Store"
}
function Import-Store {
Param(
[Parameter(Position=0)][string]$File,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
#### This will overwrite the current system store--use with caution! ####
$BcdStore | Invoke-Method "ImportStore"
"File" $File | Get-PropertyValue "ReturnValue"
}
function Import-StoreWithFlags {
Param(
[Parameter(Position=0)][string]$File,
[Parameter(Position=1)][int]$Flags=0,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "ImportStoreWithFlags"
"File","Flags" $File,$Flags | Get-PropertyValue "ReturnValue"
}
function Export-Store {
Param(
[Parameter(Position=0)][string]$File,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "ExportStore"
"File" $File | Get-PropertyValue "ReturnValue"
}
function Create-Store {
Param(
[Parameter(Position=0)][string]$File,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "CreateStore"
"File" $File | Get-PropertyValue "Store"
}
function Delete-SystemStore {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdStore)
$BcdStore | Invoke-Method "DeleteSystemStore" | Get-PropertyValue "ReturnValue"
}
function Get-SystemDisk {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdStore)
$BcdStore | Invoke-Method "GetSystemDisk" | Get-PropertyValue "Disk"
}
function Get-SystemPartition {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdStore)
$BcdStore | Invoke-Method
"GetSystemPartition" | Get-PropertyValue "Partition"
}
function Set-SystemStoreDevice {
Param(
[Parameter(Position=0)]$Partition,
[Parameter(Mandatory=$true, Position=2, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method
"SetSystemStoreDevice" | Get-PropertyValue "ReturnValue"
}
function Enumerate-Objects {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "EnumerateObjects"
"Type" $Type | Get-PropertyValue "Objects"
}
function Open-Object {
Param(
[Parameter(Position=0)][string]$Id,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "OpenObject"
"Id" $Id | Get-PropertyValue "Object"
}
function Create-Object {
Param(
[Parameter(Position=0)][uint32]$Type,
[Parameter(Position=1)][string]$Id,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "CreateObject"
"Id","Type" $Id,$Type | Get-PropertyValue "Object"
}
function Delete-Object {
Param(
[Parameter(Position=0)][string]$Id,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "DeleteObject"
"Id" $Id | Get-PropertyValue "ReturnValue"
}
function Copy-Object {
Param(
[Parameter(Position=0)][string]$SourceStoreFile,
[Parameter(Position=1)][string]$SourceId,
[Parameter(Position=2)][int]$Flags,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "CopyObject" "SourceStoreFile",
"SourceId","Flags"
$SourceStoreFile,$SourceId,$Flags | Get-PropertyValue "Object"
}
function Copy-Objects {
Param(
[Parameter(Position=0)][string]$SourceStoreFile,
[Parameter(Position=1)][uint32]$Type,
[Parameter(Position=2)][int]$Flags,
[Parameter(Mandatory=$true, ValueFromPipeLine=$true)]$BcdStore
)
$BcdStore | Invoke-Method "CopyObjects" "SourceStoreFile",
"Type","Flags"
$SourceStoreFile,$Type,$Flags | Get-PropertyValue "ReturnValue"
}
#################################
### Other Bcd Objects ###
#################################
function Get-StoreFilePath {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Get-PropertyValue "StoreFilePath"
}
function Get-Id {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Get-PropertyValue "Id"
}
function Get-Type {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Get-PropertyValue "Type"
}
function Get-Path {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Get-PropertyValue "Path"
}
function Get-ElementProperty {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Get-PropertyValue "Element"
}
function Get-Parent {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdObject)
$BcdObject | Get-PropertyValue "Parent"
}
function Get-ObjectId {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdElement)
$BcdElement | Get-PropertyValue "ObjectId"
}
function Get-Data {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdDeviceUnknownData)
$BcdDeviceUnknownData | Get-PropertyValue "Data"
}
function Get-Device {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdDeviceElement)
$BcdDeviceElement | Get-PropertyValue "Device"
}
function Get-DeviceType {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdDeviceData)
$BcdDeviceData | Get-PropertyValue "DeviceType"
}
function Get-AdditionalOptions {
Param([Parameter(Mandatory=$true, Position=0, ValueFromPipeLine=$true)]$BcdDeviceData)
$BcdDeviceData | Get-PropertyValue "AdditionalOptions"
}
function Get-PartitionStyle {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdDeviceQualifiedPartitionData)
$BcdDeviceQualifiedPartitionData | Get-PropertyValue "PartitionStyle"
}
function Get-DiskSignature {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdDeviceQualifiedPartitionData)
$BcdDeviceQualifiedPartitionData | Get-PropertyValue "DiskSignature"
}
function Get-PartitionIdentifier {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdDeviceQualifiedPartitionData)
$BcdDeviceQualifiedPartitionData | Get-PropertyValue "PartitionIdentifier"
}
function Get-String {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdStringElement)
Get-PropertyValue "String" -Object $BcdStringElement
}
function Get-Ids {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdObjectListElement)
Get-PropertyValue "Ids" -Object $BcdObjectListElement
}
function Get-Integer {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdIntegerElement)
Get-PropertyValue "Integer" -Object $BcdIntegerElement
}
function Get-Integers {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdIntegerListElement)
Get-PropertyValue "Integers" -Object $BcdIntegerListElement
}
function Get-Boolean {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdBooleanElement)
Get-PropertyValue "Boolean" -Object $BcdBooleanElement
}
function Get-ActualType {
Param([Parameter(Mandatory=$true, Position=0,
ValueFromPipeLine=$true)]$BcdUnknownElement)
Get-PropertyValue "ActualType" -Object $BcdUnknownElement
}
关注点
看起来 BCD 提供程序乐于接受为引导加载程序等对象提供的 GUID,尽管如果允许,它也会生成这些 GUID。看起来 "{" + [guid]::NewGuid() + "}"
可以作为替代。尽管在测试中没有发现不良影响:强烈建议使用 BCD 提供的 GUID。
Microsoft 文档可在此链接找到。
BCD 示例可在 Windows SDK 7.1:BootConfigurationData
示例,Windows Vista AIK:SetAutoFailover.cmd,以及Hey Scripting Guy! 中找到。
如前所述,BCD 的细节很少。我发现学习 BCD 的最佳方法是检查 BCD 文件。使用 COM 的一大好处是可以迭代 Properties_
,而无需预先知道 Id
或 Type
。
额外说明:此代码最初是为 PowerShell 4.0 编写的,为 PowerShell 5 所需的代码更改。
历史
- 2014年11月1日 - 首次发布
- 2018年2月19日 - 添加了注释
- 2020年11月1日 - 添加了 PowerShell 5 更新