Using PowerShell to Create a BCD File

Recently, I was curious to see if I could get 1E PXE Everywhere (included with 1E Nomad) to boot a MDT Lite Touch boot image.  Since PXE Everywhere integrates with System Center Configuration Manager, it automatically creates the necessary BCD files based on the ConfigMgr boot images.  So that left me with using the command line utility bcdedit to generate the BCD file that I needed for the MDT Boot Image.  Not that there is anything wrong with bcdedit, it just requires a bit of typing out long commands.  It returns a GUID when the OSLOADER is create that then needs to be used in some of the follow up commands.  This is where I thought it would be nice to have a simple PowerShell cmdlet to do it for me – the only problem is one does not currently exist.  So after a bit of playing around with the syntax, I came up with the following function below.  It still calls bcdedit, but because of the way PowerShell uses certain characters, it is necessary to use various escape techniques.

This is a quick script to get the job done, so there is not any type of error handling or logging.  Also, I follow the PXE Everywhere naming convention of boot.xxxxx.bcd, so feel free to modify the script to your needs or preferences.

#Create-BCD
#Author: Mike Terrill
#Version 1.0

#Disclaimer:
#Your use of these example scripts or cmdlets is at your sole risk. This information is provided “as-is”, without any warranty, whether express or implied, of accuracy,
#completeness, fitness for a particular purpose, title or non-infringement. I shall not be liable for any damages you may sustain by using these examples, whether direct,
#indirect, special, incidental or consequential.

#Usages:
#Create-BCD Name Platform TFTPBlockSize
#Example:
#Create-BCD LiteTouchPE x64 8192
#Will create a BCD file called boot.LiteTouchPE_x64.bcd with a TFTPBlockSize of 8192

function Create-BCD {
    [CmdletBinding()]
    param (
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Name,
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Platform,
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)][int]$TFTPBlockSize
    )

    $ImageName = $Name + "_" + $Platform
    $BCDFileName = "boot.$ImageName.bcd"
    bcdedit /createstore $BCDFileName
    bcdedit /store $BCDFileName /create "{bootmgr}"
    bcdedit /store $BCDFileName /set --%{bootmgr} description "Boot Manager"
    bcdedit /store $BCDFileName /set --%{bootmgr} fontpath \Boot\Fonts
    bcdedit /store $BCDFileName /create --%{ramdiskoptions} /d "Windows PE"
    bcdedit /store $BCDFileName /set --%{ramdiskoptions} ramdisksdidevice boot
    bcdedit /store $BCDFileName /set --%{ramdiskoptions} ramdisksdipath \boot.sdi
    #Grab the output that contains the GUID
    $x = bcdedit /store $BCDFileName /create /d "$ImageName" /application OSLOADER
    $GUID = $x|%{$_.split(' ')[2]}
    bcdedit /store $BCDFileName /default $GUID
    cmd /c "bcdedit /store $BCDFileName /set {default} device ramdisk=[boot]\Images\$ImageName\boot.$ImageName.wim,{ramdiskoptions}"
    cmd /c "bcdedit /store $BCDFileName /set {default} osdevice ramdisk=[boot]\Images\$ImageName\boot.$ImageName.wim,{ramdiskoptions}"
    bcdedit /store $BCDFileName /set --%{default} systemroot \WINDOWS
    bcdedit /store $BCDFileName /set --%{default} winpe Yes
    bcdedit /store $BCDFileName /set --%{default} detecthal Yes
    cmd /c "bcdedit /store $BCDFileName /set {ramdiskoptions} ramdisktftpblocksize $TFTPBlockSize"
    }

Using the example inputs will generate the following output (bcdedit /store boot.LiteTouchPE_x64.bcd /enum all):

Windows Boot Manager
--------------------
identifier              {bootmgr}
description             Boot Manager
fontpath                \Boot\Fonts
default                 {default}

Windows Boot Loader
-------------------
identifier              {default}
device                  ramdisk=[boot]\Images\LiteTouchPE_x64\boot.LiteTouchPE_x64.wim,{ramdiskoptions}
description             LiteTouchPE_x64
osdevice                ramdisk=[boot]\Images\LiteTouchPE_x64\boot.LiteTouchPE_x64.wim,{ramdiskoptions}
systemroot              \WINDOWS
detecthal               Yes
winpe                   Yes

Setup Ramdisk Options
---------------------
identifier              {ramdiskoptions}
description             Windows PE
ramdisksdidevice        boot
ramdisksdipath          \boot.sdi
ramdisktftpblocksize    8192

And if you were wondering if I got 1E PXE Everywhere to boot a MDT LiteTouch boot image – the answer is absolutely!

Originally posted on https://miketerrill.net/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s