build-pe-script-launcher/lib/PowerShell7.psm1
Claude b06374a562 Initial commit: Build PE Script Launcher
Production-grade Windows PE builder with PowerShell 7 integration.

Features:
- PowerShell 7 integrated into WinPE environment
- Automatic script launcher for external media
- Configurable startup and fallback scripts
- Custom console colors
- Maximized console window on boot
- PowerShell module integration
- Windows ADK auto-installation
- Defender optimization for faster builds

Project Structure:
- Build-PE.ps1: Main build orchestrator
- config.json: Configuration file
- lib/: Build modules (Dependencies, WinPEBuilder, PowerShell7, ModuleManager, DefenderOptimization)
- resources/: Runtime scripts (Invoke-ScriptLauncher, Invoke-ScriptMenu, Driver-Manager)
- CLAUDE.md: Complete project documentation
- README.md: Quick start guide

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-12 16:39:43 -05:00

142 lines
4.3 KiB
PowerShell

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'
)