While not officially supported, PowerShell 7 seems to play somewhat nicely in WinPE. Here is a short script that adds it into WinPE build 10.1.22000.1 (Windows ADK for Windows 11 21H2) or WinPE build 10.0.22621.1 (Windows ADK for Windows 11 22H2).
Update July 2, 2022: Added code to support PowerShell Gallery, set screen resolution and to launch PowerShell 7 automatically.
Note #1: This will probably work in older Windows ADK versions as well, I just haven't tried.
Note #2: If you stumble of any PowerShell 7 code that doesn't work in WinPE, but works in Window, please let me know in the comments.

Download PowerShell 7
First, download the ZIP version of the latest PowerShell 7, at the time of writing this blog post it was 7.2.5: https://github.com/PowerShell/PowerShell/releases/latest. For this example, I downloaded PowerShell-7.2.5-win-x64.zip and saved it in my C:\Setup folder.
Adding PowerShell 7 to WinPE using PowerShell
Here is the script that adds PowerShell 7 (and some other components to WinPE) as well as sets the environment variables for it.
<#
.Synopsis
Sample script for Deployment Research
.DESCRIPTION
Created: 2022-07-01
Version: 1.0
Author : Johan Arwidmark
Twitter: @jarwidmark
Blog : https://deploymentresearch.com
Disclaimer: This script is provided "AS IS" with no warranties, confers no rights and
is not supported by the author or DeploymentArtist..
.EXAMPLE
N/A
#>
#Requires -RunAsAdministrator
# Settings
$PowerShell7File = "C:\Setup\PowerShell-7.2.5-win-x64.zip"
$WinPE_BuildFolder = "C:\Setup\WinPE_x64"
$WinPE_Architecture = "amd64" # Or x86
$WinPE_MountFolder = "C:\Mount"
$WinPE_ISOFolder = "C:\ISO"
$WinPE_ISOfile = "$WinPE_ISOFolder\WinPE11_x64_PowerShell7.iso"
$ADK_Path = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit"
$WinPE_ADK_Path = $ADK_Path + "\Windows Preinstallation Environment"
$WinPE_OCs_Path = $WinPE_ADK_Path + "\$WinPE_Architecture\WinPE_OCs"
$DISM_Path = $ADK_Path + "\Deployment Tools" + "\$WinPE_Architecture\DISM"
$OSCDIMG_Path = $ADK_Path + "\Deployment Tools" + "\$WinPE_Architecture\Oscdimg"
# Validate locations
If (!(Test-path $OSCDIMG_Path)){ Write-Warning "OSCDIMG Path does not exist, aborting...";Break}
If (!(Test-path $PowerShell7File)){ Write-Warning "PowerShell7File Path does not exist, aborting...";Break}
# Delete existing WinPE build folder (if exist)
try
{
if (Test-Path -path $WinPE_BuildFolder) {Remove-Item -Path $WinPE_BuildFolder -Recurse -ErrorAction Stop}
}
catch
{
Write-Warning "Oupps, Error: $($_.Exception.Message)"
Write-Warning "Most common reason is existing WIM still mounted, use DISM /Cleanup-Wim to clean up and run script again"
Break
}
# Create Mount folder
New-Item -Path $WinPE_MountFolder -ItemType Directory -Force
# Create ISO folder
New-Item -Path $WinPE_ISOFolder -ItemType Directory -Force
# Make a copy of the WinPE boot image from Windows ADK
if (!(Test-Path -path "$WinPE_BuildFolder\Sources")) {New-Item "$WinPE_BuildFolder\Sources" -Type Directory}
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\en-us\winpe.wim" "$WinPE_BuildFolder\Sources\boot.wim"
# Copy WinPE boot files
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\*" "$WinPE_BuildFolder" -Recurse
# Mount the WinPE image
$WimFile = "$WinPE_BuildFolder\Sources\boot.wim"
Mount-WindowsImage -ImagePath $WimFile -Path $WinPE_MountFolder -Index 1
# Add native WinPE optional components (using ADK version of dism.exe instead of Add-WindowsPackage)
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-WMI.cab # Install WinPE-WMI before you install WinPE-NetFX (dependency)
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\en-us\WinPE-WMI_en-us.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-NetFx.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\en-us\WinPE-NetFx_en-us.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-PowerShell.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\en-us\WinPE-PowerShell_en-us.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-DismCmdlets.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\en-us\WinPE-DismCmdlets_en-us.cab
# Add PowerShell 7
Expand-Archive -Path $PowerShell7File -DestinationPath "$WinPE_MountFolder\Program Files\PowerShell\7" -Force
# Update the offline environment PATH for PowerShell 7
$HivePath = "$WinPE_MountFolder\Windows\System32\config\SYSTEM"
reg load "HKLM\OfflineWinPE" $HivePath
Start-Sleep -Seconds 5
# Add PowerShell 7 Paths to Path and PSModulePath
$RegistryKey = "HKLM:\OfflineWinPE\ControlSet001\Control\Session Manager\Environment"
$CurrentPath = (Get-Item -path $RegistryKey ).GetValue('Path', '', 'DoNotExpandEnvironmentNames')
$NewPath = $CurrentPath + ";%ProgramFiles%\PowerShell\7\"
$Result = New-ItemProperty -Path $RegistryKey -Name "Path" -PropertyType ExpandString -Value $NewPath -Force
$CurrentPSModulePath = (Get-Item -path $RegistryKey ).GetValue('PSModulePath', '', 'DoNotExpandEnvironmentNames')
$NewPSModulePath = $CurrentPSModulePath + ";%ProgramFiles%\PowerShell\;%ProgramFiles%\PowerShell\7\;%SystemRoot%\system32\config\systemprofile\Documents\PowerShell\Modules\"
$Result = New-ItemProperty -Path $RegistryKey -Name "PSModulePath" -PropertyType ExpandString -Value $NewPSModulePath -Force
# Add additional environment variables for PowerShell Gallery Support
$APPDATA = "%SystemRoot%\System32\Config\SystemProfile\AppData\Roaming"
$Result = New-ItemProperty -Path $RegistryKey -Name "APPDATA" -PropertyType String -Value $APPDATA -Force
$HOMEDRIVE = "%SystemDrive%"
$Result = New-ItemProperty -Path $RegistryKey -Name "HOMEDRIVE" -PropertyType String -Value $HOMEDRIVE -Force
$HOMEPATH = "%SystemRoot%\System32\Config\SystemProfile"
$Result = New-ItemProperty -Path $RegistryKey -Name "HOMEPATH" -PropertyType String -Value $HOMEPATH -Force
$LOCALAPPDATA = "%SystemRoot%\System32\Config\SystemProfile\AppData\Local"
$Result = New-ItemProperty -Path $RegistryKey -Name "LOCALAPPDATA" -PropertyType String -Value $LOCALAPPDATA -Force
# Cleanup (to prevent access denied issue unloading the registry hive)
Get-Variable Result | Remove-Variable
Get-Variable RegistryKey | Remove-Variable
[gc]::collect()
Start-Sleep -Seconds 5
# Unload the registry hive
reg unload "HKLM\OfflineWinPE"
# Write winpeshl.ini that launches PowerShell 7
$winpeshl = @'
[LaunchApps]
%WINDIR%\System32\wpeinit.exe
%ProgramFiles%\PowerShell\7\pwsh.exe
'@ | Out-File "$WinPE_MountFolder\Windows\System32\winpeshl.ini" -Force
# Write unattend.xml file to change screen resolution
$UnattendPEx64 = @'
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<Display>
<ColorDepth>32</ColorDepth>
<HorizontalResolution>1280</HorizontalResolution>
<RefreshRate>60</RefreshRate>
<VerticalResolution>720</VerticalResolution>
</Display>
</component>
</settings>
</unattend>
'@ | Out-File "$WinPE_MountFolder\Unattend.xml" -Encoding utf8 -Force
# Unmount the WinPE image and save changes
Dismount-WindowsImage -Path $WinPE_MountFolder -Save
# Create a bootable WinPE ISO file (comment out if you don't need the ISO)
$BootData='2#p0,e,b"{0}"#pEF,e,b"{1}"' -f "$OSCDIMG_Path\etfsboot.com","$OSCDIMG_Path\efisys.bin"
$Proc = Start-Process -FilePath "$OSCDIMG_Path\oscdimg.exe" -ArgumentList @("-bootdata:$BootData",'-u2','-udfver102',"$WinPE_BuildFolder","$WinPE_ISOfile") -PassThru -Wait -NoNewWindow
if($Proc.ExitCode -ne 0)
{
Throw "Failed to generate ISO with exitcode: $($Proc.ExitCode)"
}
$devDetail = (Get-CimInstance -CimSession $session -Namespace root/cimv2/mdm/dmmap -Class MDM_DevDetail_Ext01 -Filter "InstanceID='Ext' AND ParentID='./DevDetail'")
..to get HardwareHashes, does not work..
It's not supported to gather hardware hashes in WinPE. Only in full Windows.
How do i use this script?
It wont run as an ps1 or as a cmd file?
it spits out errors on your Variables in the script.
I have used the guide from Microsoft for the Powershell 1.0, so that part works, but i would like to have 7 now, and get rid of the notice for Updates.
The Microsoft-way works.
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/winpe-adding-powershell-support-to-windows-pe?view=windows-11
This is just a regular PowerShell script. Run it from PowerShell, or PowerShell ISE, or VS Code.
I tried it and it works. But too bad it's working only if original powershell is integrated.
Hi Dan,
What commands didn't work without the original PowerShell?
Get-Disk, Clear-Disk, New-Partition, Get-Partition. Also, Get-Counter (unable to load pdh.dll or one of its dependencies). Probably there are more. But I think I know why. If I don't integrate powershell 5.0, the environment variable path is missing the path to c:Windows\System32\WindowsPowerShell\v1.0.
Hi Dan,
Thanks for the info.
Missing WinPE-Scripting.cab, WinPE-Scripting_en-us.cab, WinPE-StorageWMI.cab and WinPE-StorageWMI_en-us.cab to make disk commands work