function Install-PowerShell7ToWinPE { <# .SYNOPSIS Extracts and installs PowerShell 7 to the mounted WinPE image. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$ZipPath, [Parameter(Mandatory = $true)] [string]$MountDir ) Write-Host "Installing PowerShell 7 to WinPE..." -ForegroundColor Yellow if (-not (Test-Path $ZipPath)) { throw "PowerShell 7 zip not found: $ZipPath" } $ps7DestPath = Join-Path $MountDir "Program Files\PowerShell\7" if (Test-Path $ps7DestPath) { Write-Host " Removing existing PowerShell 7 installation..." -ForegroundColor Cyan Remove-Item $ps7DestPath -Recurse -Force } New-Item -ItemType Directory -Path $ps7DestPath -Force | Out-Null Write-Host " Extracting PowerShell 7..." -ForegroundColor Cyan try { Expand-Archive -Path $ZipPath -DestinationPath $ps7DestPath -Force Write-Host " ✓ PowerShell 7 extracted to: $ps7DestPath" -ForegroundColor Green } catch { throw "Failed to extract PowerShell 7: $_" } $pwshExePath = Join-Path $ps7DestPath "pwsh.exe" if (-not (Test-Path $pwshExePath)) { throw "pwsh.exe not found after extraction. Archive may be corrupt." } Write-Host " ✓ PowerShell 7 installed successfully" -ForegroundColor Green } function Set-PowerShell7Environment { <# .SYNOPSIS Configures startnet.cmd to add PowerShell 7 to PATH and set up the environment. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$MountDir, [Parameter(Mandatory = $true)] [string]$LauncherScriptPath ) Write-Host "Configuring WinPE startup script..." -ForegroundColor Yellow $startnetPath = Join-Path $MountDir "Windows\System32\startnet.cmd" if (-not (Test-Path $startnetPath)) { throw "startnet.cmd not found at: $startnetPath" } $startnetContent = @" @echo off echo. echo ===================================== echo WinPE Script Launcher Environment echo ===================================== echo. wpeinit REM Add PowerShell 7 to PATH set PATH=%PATH%;X:\Program Files\PowerShell\7 echo Initializing script launcher... echo. REM Launch the script launcher with PowerShell 7 pwsh.exe -ExecutionPolicy Bypass -File X:\Windows\System32\$LauncherScriptPath REM If launcher exits, drop to PowerShell 7 prompt pwsh.exe -NoExit -ExecutionPolicy Bypass -Command "& { `$host.UI.RawUI.WindowTitle = 'WinPE - PowerShell 7'; try { `$w = Add-Type -MemberDefinition '[DllImport(\"kernel32.dll\")] public static extern IntPtr GetConsoleWindow();' -Name Console -Namespace Win32 -PassThru; `$h = `$w::GetConsoleWindow(); `$SW_MAXIMIZE = 3; Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class User32 { [DllImport(\"user32.dll\")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); }'; [User32]::ShowWindow(`$h, `$SW_MAXIMIZE) | Out-Null } catch { } }" "@ Set-Content -Path $startnetPath -Value $startnetContent -Encoding ASCII Write-Host " ✓ Startup script configured" -ForegroundColor Green Write-Host " - PowerShell 7 added to PATH" -ForegroundColor Cyan Write-Host " - Launcher script: $LauncherScriptPath" -ForegroundColor Cyan } function Test-PowerShell7Installation { <# .SYNOPSIS Validates that PowerShell 7 was installed correctly in the WinPE image. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$MountDir ) $ps7Path = Join-Path $MountDir "Program Files\PowerShell\7" $pwshExe = Join-Path $ps7Path "pwsh.exe" if (-not (Test-Path $ps7Path)) { return $false } if (-not (Test-Path $pwshExe)) { return $false } $requiredFiles = @( "pwsh.dll", "System.Management.Automation.dll", "Microsoft.PowerShell.ConsoleHost.dll" ) foreach ($file in $requiredFiles) { $filePath = Join-Path $ps7Path $file if (-not (Test-Path $filePath)) { Write-Warning "Missing required file: $file" return $false } } return $true } Export-ModuleMember -Function @( 'Install-PowerShell7ToWinPE', 'Set-PowerShell7Environment', 'Test-PowerShell7Installation' )