-
-
Save Marcuzzo/e336e5d3a44f012029ff to your computer and use it in GitHub Desktop.
a simple script to build a WinPE image ( this is far from perfect but does the job for me )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# requires -Version 4 | |
# Requires -RunAsAdministrator | |
<# | |
.SYNOPSIS | |
Create a custom WinPE image from scratch | |
.DESCRIPTION | |
This CmdLet allows you to create a custom WinPE image from Scratch | |
.EXAMPLE | |
Another example of how to use this cmdlet | |
.NOTES | |
ScriptName : Build_WinPE.ps1 | |
Author : Marco Micozzi | |
Date : | |
License : GPL v3 | |
Requirements: ADK | |
#> | |
#region Parameters | |
[CmdLetBinding()] | |
Param( | |
[Parameter(Mandatory = $true)] | |
[ValidateSet('8.1', '10')] | |
[string] $Version, | |
[Parameter( HelpMessage = 'The CPU architecture, can be either x86, amd64 or ia64.', Mandatory = $false)] | |
[ValidateSet('x86', 'amd64', 'ia64')] | |
[Alias('CPU', 'arc', 'proc')] | |
[string] $Architecture = 'amd64', | |
[Parameter( HelpMessage = 'Set the language used in the WinPE environment. Defaults to en-us')] | |
[ValidateSet('en-us', 'en-gb', 'nl-be', 'nl-nl', | |
'de-de', 'it-it', 'fr-fr', 'fr-be')] | |
[Alias('inlang')] | |
[string] $InputLanguage = 'nl-be', | |
[Parameter( HelpMessage = 'Set the language used in the WinPE environment. Defaults to en-us')] | |
[ValidateSet('en-us', 'en-gb', 'nl-be', 'nl-nl', | |
'de-de', 'it-it', 'fr-fr', 'fr-be')] | |
[Alias('syslang')] | |
[string] $SystemLanguage = 'en-us', | |
[Parameter( HelpMessage = 'The label of the produced ISO image file.')] | |
[Alias('Label', 'lbl')] | |
[string] $ISOLabel = 'Custom WinPE', | |
[Parameter( HelpMessage = 'The temporary directory where the PE will be built.')] | |
[Alias('BuildDir', 'blddir', 'bldir')] | |
[string] $BuildDirectory = 'C:\Temp\WinPE', | |
[Parameter( HelpMessage = 'Clean the BuildDirectory before starting the script')] | |
[switch] $Clean, | |
[Parameter( HelpMessage = 'Define a list of optional packages to add to the WinPE')] | |
[Alias('pkg')] | |
[ValidateSet('HTA', 'WMI', 'Scripting', 'NetFX', 'PowerShell', | |
'StorageWMI', 'DismCmdlets', 'LegacySetup')] | |
[string[]] $Packages = @('HTA', 'WMI', 'NetFX', 'Scripting', 'PowerShell', 'StorageWMI', 'DismCmdlets'), | |
[Parameter( HelpMessage = 'Indicates that an ISO should be created for the custom WinPE.' )] | |
[Alias('Make', 'Build', 'm')] | |
[switch] $MakeIso | |
) | |
# BUG: the script fails if the build directory exists | |
#endregion Parameters | |
#region Imports | |
# Import the module with common functions | |
#Import-Module $PSScriptRoot\common.psm1 | |
#endregion Imports | |
#region Variables | |
[string] $MountDirectory = "$BuildDirectory\mount" | |
[string] $BootWIM = "$MountDirectory\ISO\sources\boot.wim" | |
#System32 is used in all Architecture types for our purposes. | |
[string] $SystemPath = "$MountDirectory\Windows\System32" | |
#endregion | |
#region Set Path | |
[string] $KitsRoot = "C:\Program Files (x86)\Windows Kits\$Version" #Get-KitsRoot | |
#[string] $ADKInstallationPath = "$(Get-ProgramFiles32)\Windows Kits\8.1\Assessment and Deployment Kit" | |
[string] $ADKPath = "$KitsRoot\Assessment and Deployment Kit" | |
[string] $DandIRoot = "$ADKPath\Deployment Tools" | |
[string] $WinPERoot = "$ADKPath\Windows Preinstallation Environment" | |
[System.Environment]::SetEnvironmentVariable("WinPERoot", $WinPERoot, "process") | |
# not sure if I should be using this here: $env:PROCESSOR_ARCHITECTURE | |
[string] $DismRoot = "$DandIRoot\$Architecture\DISM" | |
[string] $BCDBootRoot = "$DandIRoot\$Architecture\BCDBoot" | |
[string] $ImagingRoot = "$DandIRoot\$Architecture\Imaging" | |
[string] $OSCDImgRoot = "$DandIRoot\$Architecture\Oscdimg" | |
[System.Environment]::SetEnvironmentVariable("OSCDImgRoot", $OSCDImgRoot, "process") | |
[string] $WdsmcastRoot = "$DandIRoot\$Architecture\Wdsmcast" | |
[string] $HelpIndexerRoot = "$DandIRoot\HelpIndexer" | |
[string] $WSIMRoot = "$DandIRoot\WSIM" | |
[string] $NewPath = "$DISMRoot;$ImagingRoot;$BCDBootRoot;$OSCDImgRoot;$WdsmcastRoot;$HelpIndexerRoot;$WSIMRoot;$WinPERoot;" | |
# store the old path | |
[string] $OldPath = $Env:Path | |
[System.Environment]::SetEnvironmentVariable("PATH", $NewPath + "$env:SystemRoot\System32", "process") | |
#$Env:Path = $NewPath | |
#endregion | |
if ( Get-Module -Name Dism ) { | |
Remove-Module -Name Dism | |
} | |
Import-Module $DismRoot | |
Clear-WindowsCorruptMountPoint | Out-Null | |
# clean up all mounted images | |
Get-WindowsImage -Mounted | ForEach-Object { | |
Write-Host "Unmounting old mount in '$($_.Path)'" | |
Dismount-WindowsImage -Path $_.MountPath -Discard | Out-Null | |
} | |
# clean the temp dir | |
if ( $Clean.IsPresent ) { | |
if ( Test-Path -Path $BuildDirectory ) { | |
Remove-Item -Path $BuildDirectory -Recurse -Force | |
} | |
} | |
#Run Dism Cleanup... not sure if needed...? | |
Write-Host "Running Imagex /Cleanup..." -NoNewline | |
Dism /Cleanup-Wim | |
Write-Host " done" -ForegroundColor Green | |
#Run CopyPE.cmd to create the initial WinPE Image | |
Write-Host "Running CopyPE..." -NoNewline | |
copype.cmd $Architecture $BuildDirectory | |
Write-Host " done" -ForegroundColor Green | |
Write-Host "Mount the image" -NoNewline | |
Try { | |
$Mount = Mount-WindowsImage -ImagePath "$BuildDirectory\media\sources\boot.wim" -Index 1 -Path $MountDirectory | |
Write-Host " done" -ForegroundColor Green | |
} | |
Catch{ | |
$message = "TRAPPED: {0}: '{1}'" -f ($_.Exception.GetType().FullName), ($_.Exception.Message) | |
Write-host "FAILED" -ForegroundColor Red | |
Exit | |
} | |
Write-Host "Adding Packages" -ForegroundColor Yellow | |
$Packages | ForEach-Object { | |
[string] $Package = "$WinPERoot\$Architecture\WinPE_OCs\WinPE-$_.cab" | |
[string] $PackageLang = "$WinPERoot\$Architecture\WinPE_OCs\$SystemLanguage\WinPE-$($_)_$SystemLanguage.cab" | |
if ( ( Test-Path -Path $Package ) -and ( Test-Path -Path $PackageLang )) | |
{ | |
Write-Host "`tAdding $_" -ForegroundColor Yellow | |
Try{ | |
Add-WindowsPackage -PackagePath $Package -Path $MountDirectory -IgnoreCheck | Out-Null | |
Add-WindowsPackage -PackagePath $PackageLang -Path $MountDirectory -IgnoreCheck | Out-Null | |
Write-Host "Done" -ForegroundColor Green | |
} | |
Catch{ | |
Write-Host "Failed" -ForegroundColor Red | |
} | |
} | |
else | |
{ | |
Write-Error "couldn't find: '$Package' or '$PackageLang'!" | |
} | |
} | |
Write-Host 'Set the input language' -ForegroundColor Yellow | |
Dism /image:"$MountDirectory" /Set-SysLocale:"$SystemLanguage" | |
Dism /image:"$MountDirectory" /Set-UserLocale:"$SystemLanguage" | |
Dism /image:"$MountDirectory" /Set-InputLocale:"$InputLanguage" | |
Copy-Item -Path "C:\Windows\System32\whoami.exe" -Destination "$SystemPath" -Force | |
Copy-Item -Path "C:\Windows\System32\shutdown.exe" -Destination "$SystemPath" -Force | |
#Copy-Item -Path "C:\Projects\Personal\NEW\todo\WinPE\Script\utilities\Winpeshl.ini" -Destination "$MountDirectory\Windows\System32\" | |
Write-Host 'Unmount the image' -NoNewline | |
Dismount-WindowsImage -Path $MountDirectory -Save | |
Write-Host " done" -ForegroundColor Green | |
if ( $MakeIso ){ | |
Write-Host "Building ISO File in '$BuildDirectory\WinPE_$Architecture.iso'" -ForegroundColor Yellow | |
[string] $BOOTDATA="1#pEF,e,b`"$BuildDirectory\fwfiles\efisys.bin`"" | |
if ( Test-Path -Path "$BuildDirectory\fwfiles\etfsboot.com" ){ | |
$BOOTDATA="2#p0,e,b`"$BuildDirectory\fwfiles\etfsboot.com`"#pEF,e,b`"$BuildDirectory\fwfiles\efisys.bin`"" | |
} | |
oscdimg -l"$ISOLabel" -bootdata:$BOOTDATA -u1 -udfver102 "$BuildDirectory\media" "$BuildDirectory\WinPE_$Architecture.iso" | |
} | |
[System.Environment]::SetEnvironmentVariable("PATH", $OldPath, "process") | |
Remove-Module Dism |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment