Category Archives: MDT

Deploy UEFI and Legacy BIOS PC using a custom WinPE

My customer has implemented a custom procedure to build Windows 7/8 machines.

Instead of using MDT or SCCM he uses a custom portal that starts a custom WinPE full of custom code/script.

Now that we need to build Surface 2 Pro devices using the corporate image, we are facing the following challenges:

  • Use a x64 version of WinPE instead the x86 version (on a UEFI device like Surface you can run only x64 operating systems)
  • Find an automatic procedure to know if the bios is legacy or UEFI native
  • Modify the diskpart script in order to fit the different bios requirements

We used WinPE 5.0 x64 from the last Windows AIK Link. This WinPE can apply both x86 and x64 images and run on native UEFI BIOS machines like Surface 2 Pro as well than Legacy BIOS devices.

The second challenge was to find out a procedure to know if we are booting from a UEFI or Legacy BIOS device.

MDT implements a built-in logic to understand the BIOS type. It was not so easy to transport/translate this logic into my custom WinPE so I found two alternatives:

  • Add Powershell feature to WinPE and try the Get-SecureBootUEFI cmdlet Link
  • Use the GetFirmwareEnvironmentVariable function from a C++ program Link

I tried the first one but it seems that the WinPE Powershell feature is only a subset of cmdlet so I was not able to use the Get-SecureBootUEFI cmdlet.

The second one needs to build a .exe that implement the function but fortunately I found this Link

I was able to use the .exe file to discover if a system is booting from UEFI or Legacy BIOS. Link

The code written by Richard Mueller is very simple:

/* Compile this with cl.exe from MS SDK, e.g. ‘cl efidetect.cpp’, that is all. */
/* IBM(c) 2011 EPL license http://www.eclipse.org/legal/epl-v10.html */

#include <windows.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
GetFirmwareEnvironmentVariableA(“”,”{00000000-0000-0000-0000-000000000000}”,NULL,0);
if (GetLastError() == ERROR_INVALID_FUNCTION)
{
// This.. is.. LEGACY BIOOOOOOOOS….
printf(“Legacy”);
return 1;
}
else
{
printf(“UEFI”);
return 0;
}
return 0;

The last point was about change the diskpart behaviour.

If the .exe is returning “Legacy” I will call diskpart with a .txt file that create the classic partitions for Legacy BIOS systems.

If the .exe is returning “UEFI” I will call diskpart with a .txt file that create the correct partitions for UEFI BIOS devices. Link