Legacy BIOS and UEFI PXE coexistence

More and more enterprises are moving towards the modern UEFI devices in their fleet, whether that be desktops, laptops or convertibles. With this migration comes a change in how they boot, including off the network utilising the PXE system to grab a operating system image of some kind (like Microsoft MDT which then splats a full blown image on to the devices).

While this change is most welcome, as UEFI has more capabilities, more secure and incredibly quick which comparing to the older legacy BIOS boot management, it does mean (possibly) supporting both systems for a period of time.

You may have stood up a new, clean system like SCCM to build these fancy, shiny devices and moved all your options in DHCP to point to said system, but what happens to the older system. DHCP scopes can only have one of each option defined in Windows Server instances. Rather than standing up a separate network (or VLAN), a separate DHCP server or a combination of the two; there is a way to support both in a more efficient manner.

Enter DHCP vendor classes and policies

Vendor classes in Windows Server DHCP are used to identify DHCP clients beyond their MAC address and the corresponding IP address they are allocated. This is done in the makeup of the packet sent via DHCP and PXE protocols from client to server as explained in RFC 4578 of the IETF. The crux of this specification is the following types of clients:

Type Architecture Name
—- —————–
0 Intel x86PC
1 NEC/PC98
2 EFI Itanium
3 DEC Alpha
4 Arc x86
5 Intel Lean Client
6 EFI IA32
7 EFI BC
8 EFI Xscale
9 EFI x86-64

Notice both type 0, which is the legacy BIOS style boot system and types 2, 6, 7, 8, 9 which are all UEFI style boot systems (although most consumer/workstation devices will be type 9).

In our DHCP system, we want these type 0 or legacy BIOS systems to go to the previous PXE environment. We achieve this with the use of DHCP policies.

DHCP policies in Windows Server DHCP are rules that use conditions to apply to a subset of clients (in our case, we use the Vendor class we will define later on) a set of DHCP options such as option 66, and 67 which define PXE environment locations.

With both vendor classes and policies in our arsenal, lets combine the two with DHCP Powershell commands to allow both systems to coexist.

Add vendor class and policy to chosen scopes

The below script will prompt the user for which DHCP scopes (in 10.x.x.1,192.x.x.1 format) will receive the new policy and add the necessary vendor class at the DHCP server level. Combined, they will direct BIOS based clients to your older PXE environment instead of attempting to connect to your new fangdangled one.

<#
.DESCRIPTION
  Powershell script to add DHCP vendor class and policies to allow Legacy BIOS based network booting (PXE) based upon information sent by client detailed in RFC 4578 (https://tools.ietf.org/html/rfc4578)
.PARAMETERS
  None - execute directly from Powershell 
.VERSION 
  1.0 
.AUTHOR 
  James Pettigrove 
.COMPATIBILITY 
  Windows 7, Windows 10 
.RELEASE DATE 
  06/04/2017 
.NOTES 
  v1.0, 20170401 - Initial Version 
#>

$dhcpServers = Get-DhcpServerInDC

$className = "PXEClient(Legacy BIOS)"
$classData = "PXEClient:Arch:00000"
$classDesc = "PXEClient:Arch:00000"

$policyName = "Legacy BIOS"
$policyDesc = "Policy for Legacy BIOS based network booting"

[array]$dhcpScopes = (Read-Host "Enter DHCP Scopes (separate with comma) to apply Legacy BIOS boot option").split(",") | %{$_.trim()}

foreach ($dhcpServer in $dhcpServers) {
    Write-Host -ForegroundColor Yellow "Checking if $className exists on $dhcpServer" 
    $classExist = Get-DhcpServerv4Class -ComputerName $dhcpServer -Name $className -Type Vendor -ErrorAction SilentlyContinue
    if (-Not $classExist) {
        Write-Host -ForegroundColor Yellow "Adding $className to $dhcpServer"
        Add-DHCPServerv4Class -ComputerName $dhcpServer -Name $className -Type Vendor -Data $classData -Description $classDesc
    }
    Foreach ($dhcpScope in $dhcpScopes) {
        Write-Host -ForegroundColor Yellow "Adding $policyName to $dhcpScope"
        Add-DhcpServerv4Policy -ComputerName $dhcpServer -ScopeId $dhcpScope -Name $policyName -Description $policyDesc -Enabled $true -Condition OR -VendorClass EQ,"$className*"
        Set-DhcpServerv4OptionValue -ComputerName $dhcpServer -ScopeId $dhcpScope -PolicyName $policyName -OptionId 066 -Value "PXESERVER.local"
	    Set-DhcpServerv4OptionValue -ComputerName $dhcpServer -ScopeId $dhcpScope -PolicyName $policyName -OptionId 067 -Value "SMSBoot\x86\wdsnbp.com"
    }
}

The only thing you will need to do is swap out “PXESERVER.local” and “SMSBoot\x86\wdsnbp.com” for the FQDN of your legacy PXE environment server and the path to the boot file respectively.

Once these values are in and the script is in a .PS1 powershell script file, run it and you will be asked to enter the scopes requiring the coexistence of the legacy and new PXE environments.

But what about if you no longer need the coexistence as you slowly migrate the endpoints to UEFI hardware?

Remove vendor class and policy to chosen scopes

The below script can be ran, whereby, once again you will be prompted for the scope details for removal of the policy.

<# 
.DESCRIPTION
  Powershell script to remove DHCP policies that allows Legacy BIOS based network booting (PXE) based upon information sent by client detailed in RFC 4578 (https://tools.ietf.org/html/rfc4578) 
.PARAMETERS
  None - execute directly from Powershell 
.VERSION
  1.0 
.AUTHOR
  James Pettigrove 
.COMPATIBILITY
  Windows 7, Windows 10 
.RELEASE DATE
  06/04/2017 
.NOTES
  v1.0, 20170401 - Initial Version 
#>

$dhcpServers = Get-DhcpServerInDC

$className = "PXEClient(Legacy BIOS)"

$policyName = "Legacy BIOS"

[array]$dhcpScopes = (Read-Host "Enter DHCP Scopes (separate with comma) to remove Legacy BIOS boot option").split(",") | %{$_.trim()}

foreach ($dhcpServer in $dhcpServers) {

    foreach ($dhcpScope in $dhcpScopes) {
        Write-Host -ForegroundColor Yellow "Removing $policyName from $dhcpScope"
        Remove-DhcpServerv4Policy -ComputerName $dhcpServer -ScopeId $dhcpScope -Name $policyName
    }
}

No edits required on the above.

The script is built with the assumation that the legacy environment will be supported for some time and thus does not remove the vendor class from the DHCP servers. However, what if you want to remove the defined vendor class from the environment too (assuming there is no more legacy endpoints to support)?

The below one liner will clear it out:

$dhcpServers = Get-DhcpServerInDC | foreach ($dhcpServer in $dhcpServers) { Remove-DHCPServerv4Class -ComputerName $dhcpServer -Name "PXEClient(Legacy BIOS)" -Type Vendor }

Gone, no more legacy vendor class.

It seems, despite the apparent limitations of DHCP in Windows Server, two worlds can happily live together.

James Written by:

Be First to Comment

Helpful? Have a question on the above?