diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 7923cc0..e675e49 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -1637,8 +1637,8 @@ function Get-Office { $officeCommand = "d:\Office\setup.exe /configure d:\Office\DeployFFU.xml" # Check if Office command is not commented out or missing and fix it if it is - if ($content[2] -ne $officeCommand) { - $content[2] = $officeCommand + if ($content[3] -ne $officeCommand) { + $content[3] = $officeCommand # Write the modified content back to the file Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $content @@ -3200,34 +3200,34 @@ function Get-FFUEnvironment { #Clean up $KBPath If (Test-Path -Path $KBPath) { WriteLog "Removing $KBPath" - Remove-Item -Path $KBPath -Recurse -Force + Remove-Item -Path $KBPath -Recurse -Force -ErrorAction SilentlyContinue WriteLog 'Removal complete' } #Clean up $DefenderPath If (Test-Path -Path $DefenderPath) { WriteLog "Removing $DefenderPath" - Remove-Item -Path $DefenderPath -Recurse -Force + Remove-Item -Path $DefenderPath -Recurse -Force -ErrorAction SilentlyContinue WriteLog 'Removal complete' } #Clean up $OneDrivePath If (Test-Path -Path $OneDrivePath) { WriteLog "Removing $OneDrivePath" - Remove-Item -Path $OneDrivePath -Recurse -Force + Remove-Item -Path $OneDrivePath -Recurse -Force -ErrorAction SilentlyContinue WriteLog 'Removal complete' } #Clean up $EdgePath If (Test-Path -Path $EdgePath) { WriteLog "Removing $EdgePath" - Remove-Item -Path $EdgePath -Recurse -Force + Remove-Item -Path $EdgePath -Recurse -Force -ErrorAction SilentlyContinue WriteLog 'Removal complete' } if (Test-Path -Path "$AppsPath\Win32" -PathType Container) { WriteLog "Cleaning up Win32 folder" - Remove-Item -Path "$AppsPath\Win32" -Recurse -Force + Remove-Item -Path "$AppsPath\Win32" -Recurse -Force -ErrorAction SilentlyContinue } if (Test-Path -Path "$AppsPath\MSStore" -PathType Container) { WriteLog "Cleaning up MSStore folder" - Remove-Item -Path "$AppsPath\MSStore" -Recurse -Force + Remove-Item -Path "$AppsPath\MSStore" -Recurse -Force -ErrorAction SilentlyContinue } Clear-InstallAppsandSysprep Writelog 'Removing dirty.txt file' @@ -3253,29 +3253,29 @@ function Clear-InstallAppsandSysprep { WriteLog "Updating $AppsPath\InstallAppsandSysprep.cmd to remove Defender Platform Update" $CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" $CmdContent -notmatch 'd:\\Defender*' | Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" - #Remove $DefenderPath - WriteLog "Removing $DefenderPath" - Remove-Item -Path $DefenderPath -Recurse -Force - WriteLog "Removal complete" + # #Remove $DefenderPath + # WriteLog "Removing $DefenderPath" + # Remove-Item -Path $DefenderPath -Recurse -Force + # WriteLog "Removal complete" } if ($UpdateOneDrive) { WriteLog "Updating $AppsPath\InstallAppsandSysprep.cmd to remove OneDrive install" $CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" $CmdContent -notmatch 'd:\\OneDrive*' | Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" - #Remove $OneDrivePath - WriteLog "Removing $OneDrivePath" - Remove-Item -Path $OneDrivePath -Recurse -Force - WriteLog "Removal complete" + # #Remove $OneDrivePath + # WriteLog "Removing $OneDrivePath" + # Remove-Item -Path $OneDrivePath -Recurse -Force + # WriteLog "Removal complete" } if ($UpdateEdge) { WriteLog "Updating $AppsPath\InstallAppsandSysprep.cmd to remove Edge install" $CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" $CmdContent -notmatch 'd:\\Edge*' | Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" - #Remove $EdgePath - WriteLog "Removing $EdgePath" - Remove-Item -Path $EdgePath -Recurse -Force - WriteLog "Removal complete" + # #Remove $EdgePath + # WriteLog "Removing $EdgePath" + # Remove-Item -Path $EdgePath -Recurse -Force + # WriteLog "Removal complete" } } diff --git a/FFUDevelopment/Create-PEMedia.ps1 b/FFUDevelopment/Create-PEMedia.ps1 new file mode 100644 index 0000000..2b641af --- /dev/null +++ b/FFUDevelopment/Create-PEMedia.ps1 @@ -0,0 +1,209 @@ +param ( + [string]$FFUDevelopmentPath = $PSScriptRoot, + [string]$adkPath = 'C:\Program Files (x86)\Windows Kits\10\', + [string]$WindowsArch = 'x64', + [bool]$CopyPEDrivers = $false, + [string]$CaptureISO = "$PSScriptRoot\WinPE_FFU_Capture_x64.iso", + [string]$DeployISO = "$PSScriptRoot\WinPE_FFU_Deploy_x64.iso", + [string]$LogFile = "$PSScriptRoot\Create-PEMedia.log", + [bool]$Capture, + [bool]$Deploy = $true +) + +function WriteLog($LogText) { + Add-Content -path $LogFile -value "$((Get-Date).ToString()) $LogText" -Force -ErrorAction SilentlyContinue + Write-Verbose $LogText +} + +function Invoke-Process { + [CmdletBinding(SupportsShouldProcess)] + param + ( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string]$FilePath, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string]$ArgumentList + ) + + $ErrorActionPreference = 'Stop' + + try { + $stdOutTempFile = "$env:TEMP\$((New-Guid).Guid)" + $stdErrTempFile = "$env:TEMP\$((New-Guid).Guid)" + + $startProcessParams = @{ + FilePath = $FilePath + ArgumentList = $ArgumentList + RedirectStandardError = $stdErrTempFile + RedirectStandardOutput = $stdOutTempFile + Wait = $true; + PassThru = $true; + NoNewWindow = $true; + } + if ($PSCmdlet.ShouldProcess("Process [$($FilePath)]", "Run with args: [$($ArgumentList)]")) { + $cmd = Start-Process @startProcessParams + $cmdOutput = Get-Content -Path $stdOutTempFile -Raw + $cmdError = Get-Content -Path $stdErrTempFile -Raw + if ($cmd.ExitCode -ne 0) { + if ($cmdError) { + throw $cmdError.Trim() + } + if ($cmdOutput) { + throw $cmdOutput.Trim() + } + } + else { + if ([string]::IsNullOrEmpty($cmdOutput) -eq $false) { + WriteLog $cmdOutput + } + } + } + } + catch { + #$PSCmdlet.ThrowTerminatingError($_) + WriteLog $_ + Write-Host "Script failed - $Logfile for more info" + throw $_ + + } + finally { + Remove-Item -Path $stdOutTempFile, $stdErrTempFile -Force -ErrorAction Ignore + + } + +} + +function New-PEMedia { + param ( + [Parameter()] + [bool]$Capture, + [Parameter()] + [bool]$Deploy + ) + #Need to use the Demployment and Imaging tools environment to create winPE media + $DandIEnv = "$adkPath`Assessment and Deployment Kit\Deployment Tools\DandISetEnv.bat" + $WinPEFFUPath = "$FFUDevelopmentPath\WinPE" + + If (Test-path -Path "$WinPEFFUPath") { + WriteLog "Removing old WinPE path at $WinPEFFUPath" + Remove-Item -Path "$WinPEFFUPath" -Recurse -Force | out-null + } + + WriteLog "Copying WinPE files to $WinPEFFUPath" + if($WindowsArch -eq 'x64') { + & cmd /c """$DandIEnv"" && copype amd64 $WinPEFFUPath" | Out-Null + } + elseif($WindowsArch -eq 'arm64') { + & cmd /c """$DandIEnv"" && copype arm64 $WinPEFFUPath" | Out-Null + } + #Invoke-Process cmd "/c ""$DandIEnv"" && copype amd64 $WinPEFFUPath" + WriteLog 'Files copied successfully' + + WriteLog 'Mounting WinPE media to add WinPE optional components' + Mount-WindowsImage -ImagePath "$WinPEFFUPath\media\sources\boot.wim" -Index 1 -Path "$WinPEFFUPath\mount" | Out-Null + WriteLog 'Mounting complete' + + $Packages = @( + "WinPE-WMI.cab", + "en-us\WinPE-WMI_en-us.cab", + "WinPE-NetFX.cab", + "en-us\WinPE-NetFX_en-us.cab", + "WinPE-Scripting.cab", + "en-us\WinPE-Scripting_en-us.cab", + "WinPE-PowerShell.cab", + "en-us\WinPE-PowerShell_en-us.cab", + "WinPE-StorageWMI.cab", + "en-us\WinPE-StorageWMI_en-us.cab", + "WinPE-DismCmdlets.cab", + "en-us\WinPE-DismCmdlets_en-us.cab" + ) + + if($WindowsArch -eq 'x64'){ + $PackagePathBase = "$adkPath`Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\" + } + elseif($WindowsArch -eq 'arm64'){ + $PackagePathBase = "$adkPath`Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\" + } + + + foreach ($Package in $Packages) { + $PackagePath = Join-Path $PackagePathBase $Package + WriteLog "Adding Package $Package" + Add-WindowsPackage -Path "$WinPEFFUPath\mount" -PackagePath $PackagePath | Out-Null + WriteLog "Adding package complete" + } + If ($Capture) { + WriteLog "Copying $FFUDevelopmentPath\WinPECaptureFFUFiles\* to WinPE capture media" + Copy-Item -Path "$FFUDevelopmentPath\WinPECaptureFFUFiles\*" -Destination "$WinPEFFUPath\mount" -Recurse -Force | out-null + WriteLog "Copy complete" + #Remove Bootfix.bin - for BIOS systems, shouldn't be needed, but doesn't hurt to remove for our purposes + #Remove-Item -Path "$WinPEFFUPath\media\boot\bootfix.bin" -Force | Out-null + # $WinPEISOName = 'WinPE_FFU_Capture.iso' + $WinPEISOFile = $CaptureISO + # $Capture = $false + } + If ($Deploy) { + WriteLog "Copying $FFUDevelopmentPath\WinPEDeployFFUFiles\* to WinPE deploy media" + Copy-Item -Path "$FFUDevelopmentPath\WinPEDeployFFUFiles\*" -Destination "$WinPEFFUPath\mount" -Recurse -Force | Out-Null + WriteLog 'Copy complete' + #If $CopyPEDrivers = $true, add drivers to WinPE media using dism + if ($CopyPEDrivers) { + WriteLog "Adding drivers to WinPE media" + try { + Add-WindowsDriver -Path "$WinPEFFUPath\Mount" -Driver "$FFUDevelopmentPath\PEDrivers" -Recurse -ErrorAction SilentlyContinue | Out-null + } + catch { + WriteLog 'Some drivers failed to be added to the FFU. This can be expected. Continuing.' + } + WriteLog "Adding drivers complete" + } + # $WinPEISOName = 'WinPE_FFU_Deploy.iso' + $WinPEISOFile = $DeployISO + + # $Deploy = $false + } + WriteLog 'Dismounting WinPE media' + Dismount-WindowsImage -Path "$WinPEFFUPath\mount" -Save | Out-Null + WriteLog 'Dismount complete' + #Make ISO + if ($WindowsArch -eq 'x64') { + $OSCDIMGPath = "$adkPath`Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg" + } + elseif ($WindowsArch -eq 'arm64') { + $OSCDIMGPath = "$adkPath`Assessment and Deployment Kit\Deployment Tools\arm64\Oscdimg" + } + $OSCDIMG = "$OSCDIMGPath\oscdimg.exe" + WriteLog "Creating WinPE ISO at $WinPEISOFile" + # & "$OSCDIMG" -m -o -u2 -udfver102 -bootdata:2`#p0,e,b$OSCDIMGPath\etfsboot.com`#pEF,e,b$OSCDIMGPath\Efisys_noprompt.bin $WinPEFFUPath\media $FFUDevelopmentPath\$WinPEISOName | Out-null + if($WindowsArch -eq 'x64'){ + if($Capture){ + $OSCDIMGArgs = "-m -o -u2 -udfver102 -bootdata:2`#p0,e,b`"$OSCDIMGPath\etfsboot.com`"`#pEF,e,b`"$OSCDIMGPath\Efisys_noprompt.bin`" `"$WinPEFFUPath\media`" `"$WinPEISOFile`"" + } + if($Deploy){ + $OSCDIMGArgs = "-m -o -u2 -udfver102 -bootdata:2`#p0,e,b`"$OSCDIMGPath\etfsboot.com`"`#pEF,e,b`"$OSCDIMGPath\Efisys.bin`" `"$WinPEFFUPath\media`" `"$WinPEISOFile`"" + } + } + elseif($WindowsArch -eq 'arm64'){ + if($Capture){ + $OSCDIMGArgs = "-m -o -u2 -udfver102 -bootdata:1`#pEF,e,b`"$OSCDIMGPath\Efisys_noprompt.bin`" `"$WinPEFFUPath\media`" `"$WinPEISOFile`"" + } + if($Deploy){ + $OSCDIMGArgs = "-m -o -u2 -udfver102 -bootdata:1`#pEF,e,b`"$OSCDIMGPath\Efisys.bin`" `"$WinPEFFUPath\media`" `"$WinPEISOFile`"" + } + + } + Invoke-Process $OSCDIMG $OSCDIMGArgs + WriteLog "ISO created successfully" + WriteLog "Cleaning up $WinPEFFUPath" + Remove-Item -Path "$WinPEFFUPath" -Recurse -Force + WriteLog 'Cleanup complete' +} +if($Capture){ + New-PEMedia -Capture $Capture +} +if($Deploy){ + New-PEMedia -Deploy $Deploy +} \ No newline at end of file