PLEASE READ FIRST!

I've now been blogging here since 2007! ...Wow, has it been that long already?! Over the years, I've covered a wide array of subjects from scripting, troubleshooting, to the occasional hobby project. I have literally heard from thousands of you over the years with questions or even just offering me a bit of thanks!

Recently, I quit my full-time job and started work on an IT business, Rhythm IT Solutions, helping other IT departments manage their IT environments. We're offering consulting & professional services (Office 365 Migrations, Network Discovery, Firewall Management, etc...) as well as Endpoint Management (AV, Patch Management EDR, Managed Backup, etc...)



If there is something (on my blog or not) that you could use some additional help with, I would LOVE to hear from you! Please feel free to reach out to me using the contact links here or the contact form on Rhythm's website.

For those wondering, I do plan on continuing my work on the blog. So don't worry! There are plenty of Greg Strike posts yet to come! 😊 Thanks for stopping by!

PLEASE READ FIRST!




You may also be interested in how to get the Microsoft iSCSI initiator working under WinPE. Check out my WinPE v3.0 and Microsoft iSCSI Initiator posting.

This script will build a custom WinPE v3.0 (Windows 7 based) environment and generate a bootable ISO.

It gives you the ability to import a custom startup script (Autostart.cmd), custom wallpaper, custom drivers, registry files and custom Program Files to create a WinPE environment that works for you. You no longer have to waste the time trying to remember those pesky WinPE commands. Let the script do it for you!

Requirements:

Windows PowerShell v1.0 or higher

Windows Automated Installation Kit (AIK) for Windows 7 (Can be installed on Windows XP, Vista, or 7)

#  Script name:    Build_WinPE.ps1
#  Created on:     2010-01-05
#  Author:         Gregory Strike
#     URL:         //www.gregorystrike.com/2010/05/17/powershell-script-to-build-a-custom-winpe-v3-0-environment/
#  Purpose:        Builds a customized WinPE v3.0 image from scratch.

# Special Files:
# Autostart.cmd - Place a file called Autostart.cmd in the $Custom_WinPE\Program Files\System\ and it will run automatically on startup.
# winpe.bmp     - Place a file called winpe.bmp in $Custom_WinPE\Program Files\System\ and it will replace the default wallpaper.

$BuildDir = "C:\Temp\WinPE";	# No Spaces due to Microsoft's CopyPE Limitation
$Architecture = "x86"           # Architecture Target (x86, amd64, ia64)
$Language = "en-us"
$WAIKInstallation = "C:\Program Files\Windows AIK"; # Path to the WAIK Installation
$ISOLabel = "IMAGER"            # Volume label for the ISO

$Custom_WinPE = "C:\Documents and Settings\Administrator\Desktop\WinPE_Files";  # The folder for your custom files
$DriversDir = "$Custom_WinPE\Drivers";          # Any drivers you wish added to the image (recursive)
$ProgramsDir = "$Custom_WinPE\Program Files";   # Files\Folders added to "X:\Program Files" (recursive)
$WindowsDir = "$Custom_WinPE\Windows";          # Files\Folders added to "X:\Windows" (recursive)
$RegistryDIr = "$Custom_WinPE\Registry";        # Imports .REG files into the registry. (recursive)
                                                # WinPE registry hives are mounted to:
                                                #   HKLM\Software --> HLKM\PE_Sys
                                                #   HKLM\System   --> HLKM\PE_Soft
                                                # You will have to adjust your .REG files accordingly

CLS;

#Ensure WAIK PETools are in the Path
#This does the same as "Windows AIK\Tools\PETools\pesetenv.cmd"
Write-Host("Checking and updating path if needed...") -Fore 'Yellow'
$Path = "";
$Path += $WAIKInstallation + "\Tools\PETools" + ";"
if ($Architecture -ne "x86"){
	$Path += $WAIKInstallation + "\Tools\x86;"
}
if ($Architecture -ne "x86"){
	$Path += $WAIKInstallation + "\Tools\x86\Servicing;"
}
$Path += $WAIKInstallation + "\Tools\" + $Architecture + ";"
$Path += $WAIKInstallation + "\Tools\" + $Architecture + "\Servicing;"
If (!$Env:Path.ToLower().Contains($Path.ToLower())){
	[System.Environment]::SetEnvironmentVariable("PATH", $Path + $Env:Path, "process")
}

#Does BuildPath already exist?  If so, Exit.
if (Test-Path -path $BuildDir){
	Write-Host("BuildDir: " + $BuildDir + " already exists.  The script will now exit.") -Fore 'Red'
	Exit
}

$BootWIM = $BuildDir + "\ISO\sources\boot.wim"
$Mount = $BuildDir + "\mount"
$SystemPath = "$Mount\Windows\System32"  #System32 is used in all Architecture types for our purposes.

#Run Dism Cleanup
Write-Host("Running Imagex /Cleanup...") -Fore 'Yellow'
ImageX /Cleanup

#Run CopyPE.cmd to create the initial WinPE Image
Write-Host("Running CopyPE...") -Fore 'Yellow'
copype.cmd $Architecture $BuildDir

#Moving .WIM image to ISO\sources Folder
Write-Host("Moving WinPE.wim file to ISO\Sources\boot.wim...") -Fore 'Yellow'
Move-Item "$BuildDir\winpe.wim" "$BootWIM"

#Mounting Image
Write-Host("Mounting Boot.wim...") -Fore 'Yellow'
#Dism /Mount-Wim /WimFile:$BootWIM /Index:1 /MountDir:$Mount
ImageX /MOUNTRW "$BootWIM" 1 "$Mount"

#Adding Packages to image
Write-Host("Adding Packages...") -Fore 'Yellow'
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-WMI.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-WMI_$Language.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-Scripting.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-Scripting_$Language.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-HTA.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-HTA_$Language.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-LegacySetup.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-LegacySetup_$Language.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-WMI.cab"
Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-WMI_$Language.cab"

#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-MDAC.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-MDAC_$Language.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-PPPoE.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-PPPoE_$Language.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-Setup.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-Setup_$Language.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-Setup-Client.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-Setup-Client_$Language.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-Setup-Server.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-Setup-Server_$Language.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-SRT.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-SRT_$Language.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\WinPE-WDS-Tools.cab"
#Dism /Image:$Mount /Add-Package /PackagePath:"$WAIKInstallation\Tools\PETools\$Architecture\WinPE_FPs\$Language\WinPE-WDS-Tools_$Language.cab"

#Adding Drivers to Image
Write-Host("Installing Drivers...") -Fore 'Yellow'
Dism /Image:$Mount /Add-Driver /Driver:$DriversDir /Recurse

#Copying Program Files Folder
Write-Host("Copying Program Files...") -Fore 'Yellow'
Copy-Item $ProgramsDir\* "$Mount\Program Files" -Recurse

#Copying Windows Folder
Write-Host("Copying to Windows Directory...") -Fore 'Yellow'
Copy-Item $WindowsDir\* "$Mount\Windows" -Recurse

#Importing Custom Registry Entries
Write-Host("Importing Custom Registry Entries...") -Fore 'Yellow'
REG LOAD HKLM\PE_Sys $Mount\Windows\System32\config\SYSTEM
REG LOAD HKLM\PE_Soft $Mount\Windows\System32\config\SOFTWARE

foreach ($file in Get-ChildItem -Path "$RegistryDir\" -Recurse)
{
	Write-Host("...Importing $file") -Fore 'Yellow'
	REG IMPORT $file
}

REG UNLOAD HKLM\PE_Sys
REG UNLOAD HKLM\PE_Soft

#If Autostart.cmd exists add it to startup.
Write-Host("Checking if $Mount\Program Files\System\Autostart.cmd exists... If so, add it to startup.") -Fore 'Yellow'
if (Test-Path -path "$Mount\Program Files\System\Autostart.cmd"){
	Write-Host("Adding Autostart.cmd to startup...") -Fore 'Yellow'
	Add-Content -Path "$SystemPath\startnet.cmd" -Value """X:\Program Files\System\Autostart.cmd"""
} else {
	Write-Host("Autostart.cmd not found...") -Fore 'Red'
}

#If Winpe.bmp exists replace the default wallpaper.
Write-Host("Checking if $Mount\Program Files\System\winpe.bmp exists... If so, replace wallpaper.") -Fore 'Yellow'
if (Test-Path -path "$Mount\Program Files\System\winpe.bmp"){
	Write-Host("Updating Wallpaper...") -Fore 'Yellow'
	Move-Item "$Mount\Program Files\System\winpe.bmp" "$SystemPath\winpe.bmp" -Force
} else {
	Write-Host("Wallpaper not found...") -Fore 'Red'
}

#Unmount image
Write-Host("Unmounting\Committing Image...") -Fore 'Yellow'
#Dism /Unmount-Wim /MountDir:$Mount /Commit
ImageX /Unmount "$Mount" /Commit

#Create ISO
Write-Host("Building ISO...") -Fore 'Yellow'
$TimeStamp = Get-Date -Format yyyy-MM-dd;
oscdimg "-n" "-l$ISOLabel" "-b$BuildDir\etfsboot.com" "$BuildDir\ISO" "$BuildDir\($TimeStamp) WinPE.iso"


PLEASE READ FIRST!

I've now been blogging here since 2007! ...Wow, has it been that long already?! Over the years, I've covered a wide array of subjects from scripting, troubleshooting, to the occasional hobby project. I have literally heard from thousands of you over the years with questions or even just offering me a bit of thanks!

Recently, I quit my full-time job and started work on an IT business, Rhythm IT Solutions, helping other IT departments manage their IT environments. We're offering consulting & professional services (Office 365 Migrations, Network Discovery, Firewall Management, etc...) as well as Endpoint Management (AV, Patch Management EDR, Managed Backup, etc...)



If there is something (on my blog or not) that you could use some additional help with, I would LOVE to hear from you! Please feel free to reach out to me using the contact links here or the contact form on Rhythm's website.

For those wondering, I do plan on continuing my work on the blog. So don't worry! There are plenty of Greg Strike posts yet to come! 😊 Thanks for stopping by!

PLEASE READ FIRST!





Gregory Strike

Husband, father, IT dude & blogger wrapped up into one good looking package.