Work

Windows PE PowerShell Imager

A comprehensive utility and guide for creating a custom WinPE environment with an asynchronous PowerShell GUI for automated Windows image deployment.

Overview

The WinPE_PS_Imager.ps1 script is a utility designed to provide a graphical user interface (GUI) within the Windows Preinstallation Environment (WinPE). It simplifies the process of wiping a system’s primary drive, partitioning it according to modern UEFI/GPT standards, and applying a selected Windows image (.wim).

Architecture & Flow

The script is built entirely in PowerShell using System.Windows.Forms to generate the GUI. It uses a single-form, multi-panel design to guide the user through the imaging process without needing multiple windows.

  1. Initialization: The script locates the WinPE boot drive, sets up a log file (ImagingLog.txt), and initializes the main form.
  2. Panel Swapping: Instead of opening new windows, the script toggles the visibility of different “Panels”.
  3. Detection: Before showing the UI, it scans for available .wim files and the primary physical disk (excluding USB drives).
  4. Execution: Once the user clicks “Next”, the imaging process begins in the background, updating the UI with status messages and a timer.

Deep Dive: Key Concepts

1. Asynchronous Execution (PowerShell Runspaces)

One of the most critical design choices in this script is the use of a PowerShell Runspace ([powershell]::Create()).

If the imaging commands (which take 10+ minutes) were run directly inside the “Next” button’s click event, the GUI would completely freeze, and Windows would likely report the application as “Not Responding.”

By placing the “Nuke and Pave” script block into a separate runspace, the heavy lifting is offloaded to a background thread. A loop in the main thread then periodically checks $SharedOutput to stream log messages back to the GUI while keeping the UI responsive.

# Create PowerShell runspace to apply image asynchronously
$install_Object = [powershell]::Create()
$install_Object.AddScript($ScriptBlock)

# Create shared collections to capture output back to the GUI
$SharedInput = New-Object System.Management.Automation.PSDataCollection[PSObject]
$SharedOutput = New-Object System.Management.Automation.PSDataCollection[PSObject]

$install_Job = $install_Object.BeginInvoke($SharedInput, $SharedOutput)

2. The “Nuke and Pave” Partition Layout

When formatting the disk, the script adheres strictly to UEFI/GPT requirements. It creates four specific partitions:

  • System (EFI): 260MB (FAT32) - Holds the bootloader files.
  • MSR: 16MB - Microsoft Reserved partition.
  • Windows: Remaining space minus 20GB (NTFS) - Where the OS is applied.
  • Recovery: 20GB (NTFS) - Houses the Windows RE environment.

3. Applying the Image

Instead of relying on dism.exe executables and parsing string output, the script utilizes native PowerShell cmdlets (Expand-WindowsImage) to apply the selected .wim index to the newly created Windows partition. Finally, bcdboot.exe is called to write the boot configuration data, making the system bootable.


Preparation Guide

To use this script, you must build a custom Windows Preinstallation Environment (WinPE).

  1. Download the Windows ADK and the corresponding Windows PE add-on.
  2. Create the working files:
    copype amd64 C:\WinPE_amd64
  3. Mount the image:
    Dism /Mount-Image /ImageFile:"C:\WinPE_amd64\media\sources\boot.wim" /index:1 /MountDir:"C:\WinPE_amd64\mount"
  4. Inject PowerShell Optional Components (OCs) like WMI, .NET Framework, Scripting, and PowerShell support using Dism /Add-Package.
  5. Modify startnet.cmd to automatically launch the GUI upon boot:
    wpeinit
    powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File X:\Scripts\WinPE_PS_Imager.ps1
  6. Commit changes and create a bootable ISO or USB drive using MakeWinPEMedia.