WinPE 4.0 - Automated Media Creation
I maintain two Windows 8 VMs for building WinPE 4.0, one for x86 and one for x64. Unlike the Windows 7 WAIK, Apparently the Windows 8 ADK can only build x86 on x86, and x64 on x64.
This Powershell 3 script is intended to be run from a network share with subdirectories containing apps (optional) and drivers (optional), and looks something like this:
.\setup_w8_ps3.ps1
.\drivers\amd64
.\drivers\source
.\drivers\x86
.\apps\amd64
.\apps\source
.\apps\x86
Source directories contain the source files and the x86 and amd64 directories contain the expanded x86 and x64 drivers, respectively.
Run the Powershell script on each of your x86 and x64 Windows 8 ADK environments, and it will build the respective WinPE 4.0 environment and .iso file.
There is one extra step for making the USB boot sticks [ MakeWinPEMedia /UFD c:\winpe_amd64 <drive letter>: ]; You can add that to the Media function if you have the USB drive plugged in.
@@@@@@@@@@@@@@@@@@@@
<#
setup_w8_ps3.ps1
Build WinPE 4.0 with PowerShell 3 cmdlets
http://technet.microsoft.com/en-us/library/hh825144.aspx
http://technet.microsoft.com/en-us/library/hh824926.aspx
ISO: MakeWinPEMEdia /ISO c:\winpe_amd64 c:\winpe_amd64\winpe.iso
USB: MakeWinPEMedia /UFD c:\winpe_amd64 <drive letter>:
Adam Sailer
2013.05.10
#>
$invoke = split-path -path $myinvocation.mycommand.path -parent
$os = gwmi Win32_OperatingSystem
$proc = gwmi Win32_Processor
$arch = 'x86'
if (($proc.AddressWidth -eq 64) -and ($proc.DataWidth -eq 64))
{ $arch = 'amd64' }
$dest = "$env:SystemDrive\winpe_$arch"; $dest
$mount = "$dest\mount"
$image = "$dest\media\sources\boot.wim"
$label = "WinPE 4.0 $arch"
$unattend = @"
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-Setup" processorArchitecture="$arch" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<Display>
<ColorDepth>32</ColorDepth>
<HorizontalResolution>1600</HorizontalResolution>
<RefreshRate>60</RefreshRate>
<VerticalResolution>900</VerticalResolution>
</Display>
</component>
</settings>
</unattend>
"@
Function Prep
{
write-host "`n`n@@ Called Prep" -Fore Magenta
$ident = $env:ProgramFiles
if (($proc.AddressWidth -eq 64) -and ($proc.DataWidth -eq 64))
{ $ident = ${env:ProgramFiles(x86)} }
$map = @{
BCDBootRoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\$arch\BCDBoot";
DandIRoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools";
DISMRoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\$arch\DISM";
HelpIndexerRoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\HelpIndexer";
ImagingRoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\$arch\Imaging";
KitsRoot = "$ident\Windows Kits\8.0\";
OSCDImgRoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\$arch\Oscdimg";
#RegKeyPath = "$key\Windows Kits\Installed Roots";
WdsmcastRoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\$arch\Wdsmcast";
WinPERoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment";
WSIMRoot = "$ident\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\WSIM";
}
$array = $env:Path.Split(';')
foreach ($key in $map.Keys)
{ $array += $map.$key; [System.Environment]::SetEnvironmentVariable($key, $map.$key, "process") }
$array = $array | sort-object -unique; $array
$path = [string]::join(';', $array)
[System.Environment]::SetEnvironmentVariable('PATH', $path, 'process')
}
Function CopySource
{
write-host "`n`n@@ Called CopySource" -Fore Magenta
remove-item $dest -recurse -force -ea SilentlyContinue
copype $arch $dest
}
Function MountCurrent
{
write-host "`n`n@@ Called MountCurrent" -Fore Magenta
Mount-WindowsImage –ImagePath $image –Index 1 -Path $mount
}
Function DismountCurrent
{
write-host "`n`n@@ Called DismountCurrent" -Fore Magenta
if (Get-WindowsImage -Mounted)
{ Dismount-WindowsImage –Path $mount -Save }
}
Function Packages
{
write-host "`n`n@@ Called Packages" -Fore Magenta
$lang = 'en-us'
## Order matters! http://technet.microsoft.com/en-us/library/hh824926.aspx
$order = @(
'winpe-wmi',
'winpe-netfx4',
'winpe-scripting',
'winpe-powershell3',
'winpE-dismCmdlets',
'winpe-hta'
)
$packages = @()
$order | % { $packages += @(dir $env:WinPERoot\$arch -rec -inc "$($_).cab", "$($_)_$($lang).cab" | sort-object -desc) }
$packages | % { write-host "`n$($_.Name)"; Add-WindowsPackage -Path $mount -PackagePath $_.FullName }
}
Function Drivers
{
write-host "`n`n@@ Called Drivers" -Fore Magenta
DISM /image:$mount /add-driver /driver:$invoke\drivers\$arch /recurse
}
Function Apps
{
write-host "`n`n@@ Called Media" -Fore Magenta
copy-item $invoke\apps\$arch $mount\Apps -recurse
$unattend | out-file -encoding ASCII $mount\unattend.xml
}
Function Media
{
write-host "`n`n@@ Called Media" -Fore Magenta
MakeWinPEMEdia /ISO c:\winpe_$arch c:\winpe_$arch\winpe_$arch.iso
}
#
#
Clear
Prep
DismountCurrent
CopySource
MountCurrent
Packages
Drivers
Apps
DismountCurrent
Media
Comments