How to Manage BCD Programmatically with WMI

The BCD WMI API gives developers essentially complete control over the contents of a store. It allows developers to create applications that use custom boot data or make complex changes to a store that are difficult or impossible with BCDEdit. Applications based on the WMI API can be run locally or remotely.
The BCD WMI provider consists of a scriptable set of classes that support programmatic access to BCD stores. The classes are exposed as COM objects, which allows applications to also be implemented in C . Although the BCD WMI provider was written primarily for Windows Vista and later versions of Windows, it can also be used with Microsoft Windows XP, Windows Server 2003, and recovery environments that support WMI.
This section provides a brief summary of the capabilities of the BCD WMI provider. For detailed information, see the documentation in the MSDN Library. For some examples of how to use the WMI API for specific tasks, see “BCD Cookbook,” later in this paper.
The BCDStore Class
The BCDStore class represents a BCD store. It allows developers to do such tasks as create stores, add or delete objects, and import the contents of a non-system store into system store. The object has one property, StoreFilePath, which contains the fully-qualified path of the object's BCD store. For convenience, the system store is represented by an empty string (""). The following table lists the object's methods.
BCDStore Methods
Method
|
Description
|
CopyObject
|
Copies the specified object from another store.
|
CopyObjects
|
Copies the objects of the specified type from another store.
|
CreateObject
|
Creates the specified object.
|
CreateStore
|
Creates a new store.
|
DeleteObject
|
Deletes the specified object.
|
DeleteSystemStore
|
Deletes the system store.
|
EnumerateObjects
|
Enumerates the objects of the specified type.
|
GetSystemDisk
|
Gets the system disk.
|
GetSystemPartition
|
Gets the system partition.
|
ExportStore
|
Exports a store to a specified file.
|
ImportStore
|
Marks the specified store as the system store.
|
OpenObject
|
Opens the specified object.
|
OpenStore
|
Opens a store.
|
The BCDObject Class
The BCDObject class represents a BCD object. It allows developers to do such tasks as add or delete elements or modify the values of existing elements. Objects are identified by a GUID and also contain a Type property that specifies the object's purpose. The following table lists the object's properties:
BCDObject Properties
Property
|
Description
|
StoreFilePath
|
The fully-qualified path of the BCD store. The system store is represented by an empty string ("").
|
Id
|
The object's GUID, in string format.
|
Type
|
The object's type.
|
The following table lists the object's methods.
BCDObject Methods
Method
|
Description
|
DeleteElement
|
Deletes the specified element.
|
EnumerateElementTypes
|
Enumerates the types of elements in the object.
|
EnumerateElements
|
Enumerates the elements in the object.
|
GetElement
|
Gets the specified element.
|
SetBooleanElement
|
Sets the specified Boolean element.
|
SetDeviceElement
|
Sets the specified device element.
|
SetFileDeviceElement
|
Sets the specified file device element.
|
SetIntegerElement
|
Sets the specified integer element.
|
SetObjectElement
|
Sets the specified object element.
|
SetObjectListElement
|
Sets the specified object list element.
|
SetPartitionDeviceElement
|
Sets the specified partition device element.
|
SetStringElement
|
Sets the specified string element.
|
BCDElement Classes
A number of classes represent elements, one for each supported data type. The base class is BCDElement, which has no methods. It supports the same three properties that are supported by BCDObject. However, with BCDElement the ID property is named ObjectID. The following table lists the classes that are derived from BCDElement.
BCDElement Types and Subclasses
Method
|
Description
|
BcdBooleanElement
|
Contains a Boolean value.
|
BcdIntegerElement
|
Contains an integer element.
|
BcdObjectElement
|
Contains an object ID.
|
BcdObjectListElement
|
Contains a list of object IDs.
|
BcdStringElement
|
Contains a string.
|
BCD Cookbook
This section contains a number of brief examples of how to use BCDEdit for common tasks. It also shows some examples of how to use the BCD WMI API to do the same tasks programmatically.
Kernel Debugging
This section shows how to use BCDEdit to enable kernel debugging and specify debug settings.
Enable Kernel Debugging
Use the following BCDEdit command to enable or disable kernel debugging for a specified boot entry.
bcdedit /debug [ID] {on | off}
ID is the GUID that is associated with a boot entry. If it is omitted, BCDEdit modifies the current boot entry by default. To specify a particular boot entry, set ID to the string form of the associated GUID. The following example enables kernel debugging for the specified entry.
bcdedit /debug {cbd971bf-b7b8-4885-951a-fa03044f5d71} on
To specify debug settings globally, use the following command.
bcdedit /dbgsettings type settings
The following examples show how to specify global debug settings for serial, 1394, and USB connections.
bcdedit /dbgsettings serial debugport:1 baudrate:115200
bcdedit /dbgsettings 1394 channel:32
bcdedit /dbgsettings USB targetname:U1
Specify Debug Settings for a specified Boot Entry
To specify debug settings for a specific boot entry, use BCDEdit to set the appropriate elements. The particular settings depend on the connection type.
bcdedit /set ID debugsetting1
bcdedit /set ID debugsetting2
...
The following example shows how to specify debug settings for a serial connection for a specified entry.
bcdedit /set {cbd971bf-b7b8-4885-951a-fa03044f5d71} debugtype serial
bcdedit /set {cbd971bf-b7b8-4885-951a-fa03044f5d71} debugport 2
bcdedit /set {cbd971bf-b7b8-4885-951a-fa03044f5d71} baudrate 115200
Specify the Default Operating System
To specify the default operating system, use:
bcdedit /default ID
ID is the GUID for the Windows boot loader boot entry that is associated with the desired operating system. For example:
bcdedit /default {cbd971bf-b7b8-4885-951a-fa03044f5d71}
To change the default boot entry to the legacy loader, set ID to {ntldr}, which is BCDEdit 's well-known name for the GUID that is associated with Ntldr.
bcdedit /default {ntldr}
The following Microsoft® Visual Basic® Script sample shows how to use the BCD WMI API to specify the default operating system. It takes a single argument, the GUID that is associated with the boot entry for the new default operating system.
set Locator = CreateObject("WbemScripting.SWbemLocator")
set Services = Locator.ConnectServer(".", "root\wmi")
Services.Security_.ImpersonationLevel = 3
DefaultOsIdentifier = WScript.Arguments(0)
'These hardcoded values will be replaced with official constants
' whenavailable.
const BootMgrId = "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"
const DefaultType = &h23000003
'
'Open up a connection to WMI BcdStore class, allowing for
'impersonation. We need to request that Backup and Restore
'privileges be granted as well.
set BcdStoreClass = GetObject("winmgmts:{impersonationlevel=impersonate,(Backup,Restore)}!" & MachineName & "root/wmi:BcdStore")
if not BcdStoreClass.OpenStore("", BcdStore) then
WScript.Echo "Couldn't open the system store!"
WScript.Quit
end if
'
' Open the "boot manager" object.
'
if not BcdStore.OpenObject(BootMgrId, BootMgr) then
WScript.Echo "Couldn't open the boot manager object!"
WScript.Quit
end if
'
' Set the boot manager's default OS object to the specified OS.
' Note that objects must be passed as strings.
'
if not BootMgr.SetObjectElement(DefaultType, DefaultOSIdentifier) then
WScript.Echo "Couldn't set the default OS value!"
WScript.Quit
end if
WScript.Echo "Successfully set the boot manager's default OS value."
Specify the Boot Manager's Timeout Value
To specify the boot manager's timeout value, use:
bcdedit /timeout Timeout
Timeout specifies the value in seconds. For example, to specify a 15-second timeout value:
bcdedit /timeout 15
Manage Boot Entries
This section shows how to manage the boot entries in BCD.
Change a Boot Entry's Description
The description is the text that appears in the list of boot entries that is displayed to the user at boot time. Use the following command to change a boot entry's description. ID is the GUID that is associated with the desired boot entry.
Bcdedit /set ID description "The new description"
For example:
bcdedit /set {802d5e32-0784-11da-bd33-000476eba25f} description "My Favorite OS"
Control How Boot Entries Appear to the User
To specify the order in which boot entries appear to the user, run the following command. ID1, ID2, and so on are the GUIDs that are associated with the boot entries. Any boot entries that are not included in the list do not appear. If only one entry is specified, the Windows boot manager simply selects that entry without displaying a list.
bcdedit /displayorder ID1 [ID2] [ID3] [...]
The following command specifies three boot entries: two identified by their GUIDS and Ntldr by its well-known name.
bcdedit /displayorder {802d5e32-0784-11da-bd33-000476eba25f}
{cbd971bf-b7b8-4885-951a-fa03044f5d71} {ntldr}
The following command adds a boot entry to the beginning or end of the current list, or removes an entry from the list.
bcdedit /displayorder ID [/addlast] [/addfirst] [/remove]
The following example adds an Ntldr entry to the end of the display order.
bcdedit /displayorder {ntldr} /addlast
It is also possible to specify a display order that applies only to the next reboot. After that, BCD reverts to the original display order. Use the following command, where the IDs are the GUIDs that are associated with the boot entries.
bcdedit /bootsequence ID1 [ID2] [ID3] ...
Create a New Windows Vista Boot Entry
The following procedure creates an additional Windows Vista boot entry. This allows a user, for example, to have separate normal and debug configurations for the same version of the operating system.
1. Make a copy of an existing Windows Vista boot entry, as shown in the following example. ID is the GUID that is associated with the boot entry to be copied. BCDEdit creates a GUID for the new boot entry.
Bcdedit /copy ID /d "New entry description"
2. The preceding command returns the GUID that is associated with the new boot entry. Use that GUID to modify the partition information, as shown in the following example. NewID is the GUID of the new boot entry, and this example sets the partition to "d:".
Bcdedit /set NewID device partition=d:
Bcdedit /set NewID osdevice partition=d:
3. Add the new boot entry to the display order. The following example adds it to the end of the list.
Bcdedit /displayorder NewID –addlast
4. Make any additional configuration changes that are required, such as enabling the kernel debugger.
Delete a Boot Entry
The following command deletes a boot entry from BCD. ID is the GUID that is associated with the boot entry.
bcdedit /delete ID
The following Visual Basic Script example shows how to use the BCD WMI API to delete a boot entry. It takes a single argument, the GUID that is associated with the boot entry to be deleted.
set Locator = CreateObject("WbemScripting.SWbemLocator")
set Services = Locator.ConnectServer(".", "root\wmi")
Services.Security_.ImpersonationLevel = 3
if WScript.Arguments.Count < 1 then
WScript.Echo "Usage: " & WScript.FullName & " " & WScript.ScriptName & " "
WScript.Quit
end if
TargetOS = WScript.Arguments(0)
'
' These hardcoded values will be replaced with official constants when
' available.
'
const BootMgrId = "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"
const DefaultType = &h23000003
const DisplayOrderType = &h24000001
set BcdStoreClass = GetObject("winmgmts:{impersonationlevel=impersonate,(Backup,Restore)}!" & "root/wmi:BcdStore")
if not BcdStoreClass.OpenStore("",BcdStore) then
WScript.Echo "Couldn't open the system store!"
WScript.Quit
end if
'
' Open the "boot manager" object.
'
if not BcdStore.OpenObject(BootMgrId, BootMgr) then
WScript.Echo "Couldn't open the boot manager object!"
WScript.Quit
end if
'
' Get the boot manager's display order list.
'
if not BootMgr.GetElement(DisplayOrderType, BootOrderList) then
WScript.Echo "Couldn't get the display order list!"
else
'
' remove the target os from the boot order list.
'
dim NewBootOrderList()
i = 0
for each OSIdentifier in BootOrderList.Ids
if not TargetOS = OSIdentifier then
redim preserve NewBootOrderList(i)
NewBootOrderList(i) = OSIdentifier
i =i 1
end if
next
if not BootMgr.SetObjectListElement(DisplayOrderType, NewBootOrderList) then
WScript.Echo "Couldn't set the new display order list!"
WScript.Quit
end if
end if
'
' Finally, delete the OS object
'
if not BcdStore.DeleteObject(TargetOS) then
WScript.Echo "Couldn't delete target OS: " & TargetOS
WScript.Quit
end if
WScript.Echo "Successfully deleted target OS: " & TargetOS
Enable PAE
The following command enables PAE for a specified boot entry. ID is the GUID that is associated with the desired boot entry. If no ID is specified, BCDEdit modifies the setting for the currently active operating system.
Bcdedit /set ID PAE ForceEnable
For example:
bcdedit /set {802d5e32-0784-11da-bd33-000476eba25f} PAE ForceEnable
Create a Boot Entry to Boot a WIM from a Hard Disk
This section shows how to create a boot entry to boot a WIM from a hard disk. It assumes that the boot drive is "c:/". The WIM is contained in boot.wim, which is a normal WIM with Winload.exe in the System32 folder.
1 Use the following set of commands to create a ramdiskoptions object in the BCD store. The string "{ramdiskoptions}" is the well-known name for the object's GUID.
bcdedit /create {ramdiskoptions} /d "Ramdisk options"
bcdedit /set {ramdiskoptions} ramdisksdidevice partition=c:
bcdedit /set {ramdiskoptions} ramdisksdipath \boot\boot.sdi
2. Create a new boot entry.
bcdedit -create /d "Display Text" /application OSLOADER
3. Step 2 returns the GUID that is associated with the newly created boot entry. It is referred to as NewGUID in the remaining examples. Run the following set of commands to configure the boot entry.
bcdedit /set {NewGUID} device ramdisk=[c:]\sources\boot.wim,{ramdiskoptions}
bcdedit /set {NewGUID} path \windows\system32\winload.exe
bcdedit /set {NewGUID} osdevice ramdisk=[c:]\sources\boot.wim,{ramdiskoptions}
bcdedit /set {NewGUID} systemroot \windows
Systems can have any number of BCD stores. However, there can be only one system store, and it controls the boot process. The /import command replaces the contents of the system store with the contents of a specified non-system store. To preserve the contents of the current system store, run the /export command to create a backup copy of the system store. To restore the original system store, import the backup copy.
The following commands save a backup copy of the system store and import a non-system store into the system store. NewStoreName is the fully-qualified name of the file that contains the non-system store, and BackupStoreName is the fully-qualified name of the file that contains the backup store.
bcdedit /export BackupStoreName
bcdedit /import NewStoreName
The following Visual Basic Script example shows how to import a specified non-system store into the system store. It takes one parameter—the fully-qualified path for the BCD store that is to become the new system store.
set Locator = CreateObject("WbemScripting.SWbemLocator")
set Services = Locator.ConnectServer(".", "root\wmi")
Services.Security_.ImpersonationLevel = 3
FilePath = WScript.Arguments(0)
'
' Retrieve the BcdStore class object and call the static
' ImportStore method on it.
'
set BcdStoreClass = Services.Get("BcdStore")
if not BcdStoreClass.ImportStore(FilePath) then
WScript.Echo "Couldn't import the system store!"
WScript.Quit
end if
WScript.Echo "Successfully imported the system store from " & FilePath & "."
Resources
The following links provide further information about BCD and the Windows boot process.
MSDN:
BCD WMI Reference
http://msdn2.microsoft.com/en-us/library/aa362677.aspx
Boot Configuration Data (BCD)
http://msdn2.microsoft.com/en-us/library/aa362692.aspx
Introduction to Boot Options
http://msdn2.microsoft.com/en-us/library/ms791478.aspx
White Paper:
EFI and Windows Vista
http://www.microsoft.com/whdc/system/platform/firmware/efibrief.mspx
|