<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

Using DHCP to Boot WDS to BIOS & UEFI with SCCM

Published on
26,210 Points
23,210 Views
Last Modified:
SCCMCanuck
IT is my life...SCCM my passion! I work full time with SCCM, Exchange, and Windows Server. I have a beautiful family and love Star Trek!
Learn how to PXE Boot both BIOS & UEFI machines with DHCP Policies and Custom Vendor Classes


One of the challenges that an IT deployment administrator may face in the field is the ability to boot both BIOS and UEFI machines from the same WDS environment. This is exactly the issue I faced when our organization decided to purchase a number of new Surface devices. These were the first set of devices that were configured to natively boot to UEFI. This leaves you to decide from an organization standpoint whether you wish to boot all your devices using UEFI or the legacy BIOS…or does it.
 
I am a strong believer that finding a workaround to a problem is not a fix to the problem. To that end modern devices such as the surface are meant to be booted using the native UEFI boot. However, many organizations may also still have legacy BIOS devices that do not support UEFI boot or just work better booting from BIOS. Whatever the reasoning behind this it is actually quite easy to setup DHCP to provide the BIOS or UEFI boot file depending on what is used.

The solution!
By using DHCP policies and custom vendor classes for the following DHCP Options:
 
Option 60
Option 66
Option 67
 
The below assumes that you have SCCM configured with a PXE enabled distribution point and a valid and configured DHCP server. You should therefore be at a configured state where you are able to PXE boot BIOS based devices.
 
Create Custom Vendor Classes for Use with your DHCP Policy
 
Think Custom Vendor Classes as Detection Method’s used to determine how devices are requesting a boot image from the DHCP server.
 
  • Open the DHCP Console and expand the IPv4 Node
  • Right-Click on ‘IPv4 Node’ and select ‘Define Vendor Classes’
  • Click ‘Add’
  • Create the UEFI 64-Bit Vendor class first by entering the following information
  • Enter the following information for the respective fields:
    • DisplayName: PXEClient (UEFI x64)
    • Description: PXEClient:Arch:00007
    • ASCII: PXEClient:Arch:00007
  • Click ‘OK’
  • Click ‘Add’
    • DisplayName: PXEClient (UEFI x86)
    • Description: PXEClient:Arch:00006
    • ASCII: PXEClient:Arch:00006
  • Click ‘OK’
  • Click ‘Add’
    • DisplayName: PXEClient (BIOS x86 & x64)
    • Description: PXEClient:Arch:00000
    • ASCII: PXEClient:Arch:00000
  • Click ‘OK’
 
Creating Custom DHCP Policies
 
UEFI 64-Bit DHCP Policy
 
  • Right-Click ‘Policies’ and click ‘New Policy’
  • Give the policy a friendly name that coincides with the your vendor class naming scheme:
    • PolicyName: PXEClient (UEFI x64)
    • Description: Delivers the correct bootfile for (UEFI x64)
  • Click ‘Next’
  • On the ‘Configure Conditions for the policy’ page click ‘add’
  • Select the ‘Value’ drop-down box and select the PXEClient (UEFI x64) vendor class that you created in previous steps
  • Ensure that you check the box ‘Append wildcard(*)’
  • Select ‘Add’
  • Select ‘Ok’
  • Click ‘Next’
  • If you want the policy to affect only a specific range within your scope configure it, otherwise select no and click ‘next’
  • On the Configure settings for the policy page ensure that ‘DHCP Standard Options’ is selected from the drop down box
  • Configure the following scope options:
    • 060: PXEClient
    • 066IP Address of the SCCM or WDS Service
    • 067: smsboot\x64\wdsmgfw.efi
  • Cick ‘Next’
  • On the Summary page click ‘Finish’
 
BIOS 32-Bit & 64-Bit DHCP Policy
 
  • Right-Click ‘Policies’ and click ‘New Policy’
  • Give the policy a friendly name that coincides with the your vendor class naming scheme:
    • PolicyName: PXEClient (BIOS x86 & x64)
    • Description: Delivers the correct bootfile for BIOS machines
  • Click ‘Next’
  • On the ‘Configure Conditions for the policy’ page click ‘add’
  • Select the ‘Value’ drop-down box and select the PXEClient (BIOS x86 & x64) vendor class that you created in previous steps
  • Ensure that you check the box ‘Append wildcard(*)’
  • Select ‘Add’
  • Select ‘Ok’
  • Click ‘Next’
  • If you want the policy to affect only a specific range within your scope configure it, otherwise select no and click ‘next’
  • On the Configure settings for the policy page ensure that ‘DHCP Standard Options’ is selected from the drop down box
  • Configure the following scope options:
    • 060: PXEClient
    • 066IP Address of the SCCM or WDS Service
    • 067: smsboot\x64\wdsnbp.com
  • Cick ‘Next’
  • On the Summary page click ‘Finish’
 
UEFI 32-Bit DHCP Policy

  • Right-Click ‘Policies’ and click ‘New Policy’
  • Give the policy a friendly name that coincides with the your vendor class naming scheme:
    • PolicyName: PXEClient (UEFI x86)
    • Description: Delivers the correct bootfile for (UEFI x86) machines
  • Click ‘Next’
  • On the ‘Configure Conditions for the policy’ page click ‘add’
  • Select the ‘Value’ drop-down box and select the PXEClient (UEFI x86) vendor class that you created in previous steps
  • Ensure that you check the box ‘Append wildcard(*)’
  • Select ‘Add’
  • Select ‘Ok’
  • Click ‘Next’
  • If you want the policy to affect only a specific range within your scope configure it, otherwise select no and click ‘next’
  • On the Configure settings for the policy page ensure that ‘DHCP Standard Options’ is selected from the drop down box
  • Configure the following scope options:
    • 060: PXEClient
    • 066IP Address of the SCCM or WDS Service
    • 067: smsboot\x86\wdsmgfw.efi
  • Cick ‘Next’
  • On the Summary page click ‘Finish’
 
Remove Default PXE Options
 
  • Ensure that you have removed the 067, 066, 060 options from the default scope options to ensure that the Policies take precedence otherwise you will end up with conflict
 
As long as you have configured everything correctly you should now have the ability to boot machines from  BIOS or UEFI. Hopefully this helps alleviate some of the stress surrounding your PXE deployments. This has worked great on all of our distribution points since implementation and has allowed our deployments to be much more flexible.
0
Comment
Author:SCCMCanuck
7 Comments

Expert Comment

by:Derek Bannard
Would you happen to know how to script this in PowerShell?  I have done everything except I cannot find where to set the Options in the Policy via PowerShell.
0
LVL 10

Author Comment

by:SCCMCanuck
Have you tried using the following with the -VendorClass Parameter?

https://technet.microsoft.com/en-us/library/jj590669(v=wps.630).aspx

You may also need the following:

https://technet.microsoft.com/en-us/library/jj590665(v=wps.630).aspx

If you do get it to work and do not mind sharing can you post your code in the comments?

Thanks
0

Expert Comment

by:Derek Bannard
Thanks, I'll give that a try tomorrow.  I'll likely use the VendorClass option in the Policy creation (https://technet.microsoft.com/en-us/library/jj590665(v=wps.630).aspx)

Would you like a copy of the completed script when it's done?
0
Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

LVL 10

Author Comment

by:SCCMCanuck
If your okay with sharing you should be able to just post it as a code snippet in the comments.

Thanks
0

Expert Comment

by:Derek Bannard
Well... couldn't figure out how to set the inner "Option" on the policy, but everything else is here.

Remember to run this in an administrative powershell prompt on the DHCP server.
You need to restart the DHCPServer service after running this and set the PXEClient settings in the 3 policies.  The BIOS policy is blank, the UEFI polcies are the default of "PXEClient".

The command to run is "Set-DHCPPXEOptions"

Enjoy!


<# 
.Synopsis
	Receives user input, gets the list of DHCP options, classes and policies, then sets them if they don't exist.
.DESCRIPTION 
	Enter the option number, class name or policy name where approporiate.
.NOTES 
	Author: Derek Bannard
.EXAMPLE
	Import-Module .\DHCPPXEOptions.psm1
	Loads the modules to perform the DHCP functions.
.EXAMPLE
	Get-DHCPOptions
	Lists missing options for use with Set-DHCPPXEOptions function.
.EXAMPLE
	Get-DHCPClasses
	Lists missing classes for use with Set-DHCPPXEOptions function.
.EXAMPLE
	Get-DHCPPolicies
	Lists missing policies for use with Set-DHCPPXEOptions function.
.EXAMPLE
	Set-DHCPPXEOptions
	Creates all missing options, classes and policies for BIOS/UEFI PXE co-existance.
#>

<#
=================================================
Error Preferences
=================================================
#>
$errpref = $ErrorActionPreference
$ErrorActionPreference = "SilentlyContinue"


<#
=================================================
Script Variables, comma separated
=================================================
#>
[string[]]$DHCPOptions = 060,066,067
[string[]]$DHCPClasses = "PXEClient:Arch:00000","PXEClient:Arch:00006","PXEClient:Arch:00007"
[string[]]$DHCPPolicies = "PXEClient (BIOS x86 & x64)","UEFI 32-Bit DHCP Policy","UEFI 64-Bit DHCP Policy"

[string[]]$rtnDHCPOptions = @()
[string[]]$rtnDHCPClasses = @()
[string[]]$rtnDHCPPolicies = @()


<#
=================================================
Script Get Functions
=================================================
#>
Function Get-DHCPOptions{
	$arrayOptions = New-Object System.Collections.ArrayList

	ForEach ($DHCPOption in $DHCPOptions){
		Try{
			If((Get-DhcpServerv4OptionDefinition -OptionId $DHCPOption) -eq $null){
				Write-Verbose "OptionId $DHCPOption is not present."
				$arrayOptions.Add($DHCPOption) | Out-Null
				}
			Else{
				Write-Verbose "OptionId $DHCPOption is already present."
				}
		}
		Catch{
		}
	}
	$global:rtnDHCPOptions = $arrayOptions
}


Function Get-DHCPClasses{
	$arrayClasses = New-Object System.Collections.ArrayList

	ForEach ($DHCPClass in $DHCPClasses){
		Try{
			If((Get-DhcpServerv4Class -Type Vendor | Where {$_.AsciiData -eq $DHCPClass}) -eq $null){
				Write-Verbose "OptionId $DHCPClass is not present."
				$arrayClasses.Add($DHCPClass) | Out-Null
				}
			Else{
				Write-Verbose "OptionId $DHCPClass is already present."
				}
		}
		Catch{
		}
	}
	$global:rtnDHCPClasses = $arrayClasses
}


Function Get-DHCPPolicies{
	$arrayPolicies = New-Object System.Collections.ArrayList

	ForEach ($DHCPPolicy in $DHCPPolicies){
		Try{
			If((Get-DhcpServerv4Policy -Name $DHCPPolicy) -eq $null){
				Write-Verbose "OptionId $DHCPPolicy is not present."
				$arrayPolicies.Add($DHCPPolicy) | Out-Null
				}
			Else{
				Write-Verbose "OptionId $DHCPPolicy is already present."
				}
		}
		Catch{
		}
	}
	$global:rtnDHCPPolicies = $arrayPolicies
}


<#
=================================================
Script Set Function
=================================================
#>
Function Set-DHCPPXEOptions{
	If($rtnDHCPOptions){
		ForEach ($rtnDHCPOption in $rtnDHCPOptions){
			If($rtnDHCPOption -eq "060"){
				Try{
					Write-Output "Adding OptionId 060..."
					Add-DhcpServerv4OptionDefinition -Name "PXEClient" -Description "PXE Support" -DefaultValue "PXEClient" -OptionId 060 -Type String
				}
				Catch{
				}
			}
			ElseIf($rtnDHCPOption -eq "066"){
				Try{
					Write-Output "Adding OptionId 066..."
					Add-DhcpServerv4OptionDefinition -Name "Boot Server Host Name" -Description "TFTP boot server host name" -OptionId 066 -Type String
				}
				Catch{
				}
			}
			ElseIf($rtnDHCPOption -eq "067"){
				Try{
					Write-Output "Adding OptionId 067..."
					Add-DhcpServerv4OptionDefinition -Name "Bootfile Name" -Description "Bootfile Name" -OptionId 067 -Type String
				}
				Catch{
				}
			}
			Else{
				Write-Output "Undefined options cannot be added!"
			}
		}
	}
	Else{
		Write-Output "No Options are required to be added."
	}


	If($rtnDHCPClasses){
		ForEach ($rtnDHCPClass in $rtnDHCPClasses){
			If($rtnDHCPClass -eq "PXEClient:Arch:00000"){
				Try{
					Write-Output "Adding PXEClient (BIOS x86 & x64) Class..."
					Add-DhcpServerv4Class -Name "PXEClient (BIOS x86 & x64)" -Type Vendor -Data "0x505845436c69656e743a417263683a3030303030" -Description "PXEClient:Arch:00000"
				}
				Catch{
				}
			}
			ElseIf($rtnDHCPClass -eq "PXEClient:Arch:00006"){
				Try{
					Write-Output "Adding UEFI 32-Bit DHCP Class..."
					Add-DhcpServerv4Class -Name "PXEClient (UEFI x86)" -Type Vendor -Data "0x505845436c69656e743a417263683a3030303036" -Description "PXEClient:Arch:00006"
				}
				Catch{
				}
			}
			ElseIf($rtnDHCPClass -eq "PXEClient:Arch:00007"){
				Try{
					Write-Output "Adding UEFI 64-Bit DHCP Class..."
					Add-DhcpServerv4Class -Name "PXEClient (UEFI x64)" -Type Vendor -Data "0x505845436c69656e743a417263683a3030303037" -Description "PXEClient:Arch:00007"
				}
				Catch{
				}
			}
			Else{
				Write-Output "Undefined classes cannot be added!"
			}
		}
	}
	Else{
		Write-Output "No Classes are required to be added."
	}


	If($rtnDHCPPolicies){
		ForEach ($rtnDHCPPolicy in $rtnDHCPPolicies){
			If($rtnDHCPPolicy -eq "PXEClient (BIOS x86 & x64)"){
				Try{
					Write-Output "Adding PXEClient (BIOS x86 & x64) Policy..."
					Add-DhcpServerv4Policy -Name "PXEClient (BIOS x86 & x64)" -Description "Delivers the correct bootfile for BIOS machines" -Condition OR -VendorClass EQ,"PXEClient (BIOS x86 & x64)*" -ProcessingOrder 1 -Enabled $True -Confirm:$False
				}
				Catch{
				}
			}
			ElseIf($rtnDHCPPolicy -eq "UEFI 32-Bit DHCP Policy"){
				Try{
					Write-Output "Adding UEFI 32-Bit DHCP Policy..."
					Add-DhcpServerv4Policy -Name "UEFI 32-Bit DHCP Policy" -Description "Delivers the correct bootfile for (UEFI x86) machines" -Condition OR -VendorClass EQ,"PXEClient (UEFI x86)*" -ProcessingOrder 3 -Enabled $True -Confirm:$False
				}
				Catch{
				}
			}
			ElseIf($rtnDHCPPolicy -eq "UEFI 64-Bit DHCP Policy"){
				Try{
					Write-Output "Adding UEFI 64-Bit DHCP Policy..."
					Add-DhcpServerv4Policy -Name "UEFI 64-Bit DHCP Policy" -Description "Delivers the correct bootfile for (UEFI x64) machines" -Condition OR -VendorClass EQ,"PXEClient (UEFI x64)*" -ProcessingOrder 2 -Enabled $True -Confirm:$False
				}
				Catch{
				}
			}
			Else{
				Write-Output "Undefined policies cannot be added!"
			}
		}
	}
	Else{
		Write-Output "No Policies are required to be added."
	}
	
	#Restart-Service "DHCPServer"
}

Get-DHCPOptions
Get-DHCPClasses
Get-DHCPPolicies

Open in new window

0

Expert Comment

by:Hyoin Wang
Many Thanks.

One more question:
I also deploy BIOS x86, but the policy covers (x86 & x64).  I will set up two 'Define Vendor Classes' for x86 and x64? But ASCII, could I set as PXEClient:Arch:00000 for both?
0

Expert Comment

by:Saeid Ansaripour
Hello
this wont work if WDS and DHCP are on same server
0

Featured Post

JavaScript Best Practices

Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

Join & Write a Comment

With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month