How to make a custom WinPE


Quoting from the Microsoft Docs, the Windows Preinstallatation Environment, aka WinPE for short,  is  “a small operating system used to install, deploy, and repair Windows 10 for desktop editions (Home, Pro, Enterprise, and Education), Windows Server, and other Windows operating systems.

Yesterday (September 29, 2020), I wrote about a WinPE based Windows installation / deployment tool. Download the custom WinPE ISO and read those instructions here: WinPE – Simple Windows deployment

Today I will use that WinPE ISO as an example of how to create a custom WinPE, and show the scripts that are required for that WinPE to work as intended. For starters, please follow Microsoft Docs instructions to create a default WinPE ISO. Alternatively, you can use my custom WinPE ISO and edit it.

Click screenshots to show them enlarged in a new tab.

1.) Mount WinPE

Create two folders, one to copy files from the WinPE ISO, and the other to use as a so-called “mount point.” In this example, I use folders D:\WinPE_Files and C:\Mount.

Mount the WinPE ISO as a virtual DVD drive (right click and select Mount). A new File Explorer window will open, showing the content of the mounted WinPE ISO. Select all files and folders, and copy them to D:\WinPE_Files. Open an elevated PowerShell, and enter the following command to mount boot.wim for offline servicing:

Mount-WindowsImage -ImagePath D:\WinPE_Files\Sources\boot.wim -Index 1 -Path C:\Mount

The path to the folder containing content copied from the mounted WinPE ISO appears in -ImagePath, and the path to the mount point in -Path.

2.) Offline servicing

When the boot.wim in WinPE has been mounted, we can start offline servicing,, edit and add files on WinPE.

When done and we save the changes, and a computer is booted from this WinPE media, a RAM disk X: will be created..Everything WinPE contains is copied to RAM disk. A Command Prompt window opens, and WinPE starts performing tasks based on the our edits.

When you know what you want your WinPE boot media to do, it’s time to start customizing it. All files like scripts and batch files, all folders you now copy to folder C:\Mount, or create in it, will later be saved to WinPE. In my case, I wanted it to do the following, in this order:

- Show a menu, letting user select a disk on which to deploy Windows
- Based on the user selection, run a DISKPART script to partition the disk
- Show a menu to let the user select which Windows edition will be deployed
- Deploy selected edition of Windows 
- Apply an answer file to the deployed Windows image
- Create Windows boot records
- Create a Windows recovery environment for the deployed Windows image
- Restart the target computer to OOBE

The goal is to create simple deployment / installation media. The user needs just two key presses, to select the Windows system disk and a Windows edition, then the rest is totally automated.

3.) Add PowerShell support

By default, WinPE does not support PowerShell:

If you want to add PS scripts to WinPE, PowerShell and its dependencies must be added to it. This Microsoft Docs article shows how to do it: WinPE: Adding Windows PowerShell support to Windows PE | Microsoft Docs

4.) Scripts

When creating and editing scripts, open Notepad or your preferred text editor elevate (Run as administrator), to allow saving in mount point folder.

Time to start scripting! First, I created a folder C:\Mount\Scripts to store all scripts. Next, I created a batch file named Deploy.cmd, which runs automatically when the computer is booted from WInPE media. This batch file will be saved in C:\Mount\Scripts.

You can view and download all scripts from my OneDrive, line numbers used in this article refer to line numbers shown in the OneDrive view. See Deploy.cmd on OneDrive.

First thing the Deploy.cmd batch does is to create a menu. Lines 1 through 21 do that:

End user will see it like this:

In lines 23 through 35, the user is asked to select a menu option. Based on that selection, a DISKPART script runs (lines 36 through 57). Notice that script paths appear as X:\Scripts\Scriptname. This is because, as I mentioned earlier, everything in WinPE is copied at boot time to RAM disk X:. Because the Scripts folder is at the root of the WInPE media, at the moment still in C:\Mount folder, its path when booted from WinPE will be X:\Scripts.

See DISKPART scripts SingleDisk.txt, DualDisk1.txt and DualDisk2.txt on OneDrive. All these DISKPART scripts will be saved in C:\Mount\Scripts.

Next, in line 70, we jump to PowerShell to run the deployment itself. We’ll come back to the rest of Deploy.cmd batch when the PS script DeployW10.ps has finished. See script DeployW10.ps1 on OneDrive. This PowerShell script will be saved in C:\Mount\Scripts.

In DeployW10.ps1, its lines 68 through 71, we set a few important variables. In line 68, we’ll find out the drive letter for a volume labelled Deploy. We set two other variables based on that. The last variable identifies on which drive Windows will be deployed, in this case drive W: which is the temporary drive letter for the Windows system disk we set in the DISKPART script:

In lines 77 through 109, we’ll check that volume Deploy contains valid Windows install files. If so, the user will be shown a list of available Windows editions, and asked to select one for deployment in lines 116 through 126:

In line 138, we will deploy Windows, based on earlier user selections. In lines 145 through 150, we’ll check to see if volume Deploy contains an answer file, and if yes, apply it to the deployed Windows image. An extract from my previous article, published yesterday (September 29, 2020) shows what to change in that answer file:

Lines 5 to 9: your localized language settings. InputLocale is the default keyboard, it and all the rest must match the language and region of your Windows 10 ISO. Some common values:
- Brazil - Portuguese > 0416:00000416, pt-BR
- Canada - English > 1009:00000409, en-CA
- Canada - French > 0c0c:00011009, fr-CA
- France - French > 040c:0000040c, fr-FR
- Germany - German > 0407:00000407, de-DE
- UK - English > 0809:00000809, en-GB
- USA - English > 0409:00000409, en-US
- Complete list: Default Input Profiles (Input Locales) in Windows | Microsoft Docs

Lines 28 and 30: Name of main admin account. DisplayName is how the name will be shown for instance on sign-in screen, Name is the name of user profile. These two do not have to be same.

Lines 35 and 49: Your local time zone. See complete list of Windows time zones:
- Microsoft Time Zone Index Values | Microsoft Docs

See answer file unattend.xml in OneDrive.. Answer file will be saved in C:\Mount, not in the Scripts folder.

When PowerShell script is finished, in line 159 we will quit PowerShell and go back to batch Deploy.cmd to finish the rest of that file’s instructions.

Windows is already deployed. We still need to create boot records, and create a Windows recovery environment. This is handled in Deploy.cmd lines 61 through 83. Finally, we will restart the computer to OOBE, which will be totally automated if an answer file was applied to deployed Windows image.

Last but not least, we will edit startnet.cmd, the default WinPE startup batch file. It functions exactly the same way as the infamous autoexec.bat did in early Windows versions, containing commands to run at boot. By default, it only contains the command wpeinit which initializes WinPE networking. We will add two more startup commands. First, we run a high performance power scheme to speed up Windows deployment, and then we add a command to run the Deploy.cmd batch file.

Run Notepad elevated (Run as administrator), otherwise the mount point folder does not allow editing and saving. Open file C:\Mount\Windows\System32\startnet.cmd, and add the required commands:

wpeinit
powercfg /s 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 
X:\Scripts\Deploy.cmd

Save the file.

All scripts and batch files except answer file unattend.xml, which is saved in C:\Mount, are saved in C:\Mount\Scripts folder.

With offline servicing done, it’s time to commit (save) changes using the following command in an elevated PowerShell:

Dismount-WindowsImage -Path C:\Mount -Save

That’s it. See my September 29 article for instructions on creating WinPE Windows deployment USB media based on these scripts.

Kari

Author: Kari Finn

A former Windows Insider MVP, Kari started in computing in the mid 80’s writing code for VAX / VMS systems. Since then, he’s worked in a variety of IT positions. He specializes in Windows image capture, customization, repair and deployment as well as Hyper-V virtualization. Kari is a proud Team Member at number #1 Windows site TenForums.com.