fixed issues creating deploy media for VMs, cleaned up some old commented code in ApplyFFU.ps1

This commit is contained in:
rbalsleyMSFT
2024-07-19 19:17:02 -07:00
parent 1d26781dc1
commit 5600b2fbbd
8 changed files with 64 additions and 769 deletions
+10 -7
View File
@@ -334,8 +334,8 @@ else {
# Set default values for variables that depend on other parameters # Set default values for variables that depend on other parameters
if (-not $AppsISO) { $AppsISO = "$FFUDevelopmentPath\Apps.iso" } if (-not $AppsISO) { $AppsISO = "$FFUDevelopmentPath\Apps.iso" }
if (-not $AppsPath) { $AppsPath = "$FFUDevelopmentPath\Apps" } if (-not $AppsPath) { $AppsPath = "$FFUDevelopmentPath\Apps" }
if (-not $DeployISO) { $DeployISO = "$FFUDevelopmentPath\WinPE_FFU_Deploy.iso" } if (-not $DeployISO) { $DeployISO = "$FFUDevelopmentPath\WinPE_FFU_Deploy_$WindowsArch.iso" }
if (-not $CaptureISO) { $CaptureISO = "$FFUDevelopmentPath\WinPE_FFU_Capture.iso" } if (-not $CaptureISO) { $CaptureISO = "$FFUDevelopmentPath\WinPE_FFU_Capture_$WindowsArch.iso" }
if (-not $OfficePath) { $OfficePath = "$AppsPath\Office" } if (-not $OfficePath) { $OfficePath = "$AppsPath\Office" }
if (-not $rand) { $rand = Get-Random } if (-not $rand) { $rand = Get-Random }
if (-not $VMLocation) { $VMLocation = "$FFUDevelopmentPath\VM" } if (-not $VMLocation) { $VMLocation = "$FFUDevelopmentPath\VM" }
@@ -2627,7 +2627,8 @@ function New-PEMedia {
WriteLog "Copy complete" WriteLog "Copy complete"
#Remove Bootfix.bin - for BIOS systems, shouldn't be needed, but doesn't hurt to remove for our purposes #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 #Remove-Item -Path "$WinPEFFUPath\media\boot\bootfix.bin" -Force | Out-null
$WinPEISOName = 'WinPE_FFU_Capture.iso' # $WinPEISOName = 'WinPE_FFU_Capture.iso'
$WinPEISOFile = $CaptureISO
$Capture = $false $Capture = $false
} }
If ($Deploy) { If ($Deploy) {
@@ -2645,7 +2646,9 @@ function New-PEMedia {
} }
WriteLog "Adding drivers complete" WriteLog "Adding drivers complete"
} }
$WinPEISOName = 'WinPE_FFU_Deploy.iso' # $WinPEISOName = 'WinPE_FFU_Deploy.iso'
$WinPEISOFile = $DeployISO
$Deploy = $false $Deploy = $false
} }
WriteLog 'Dismounting WinPE media' WriteLog 'Dismounting WinPE media'
@@ -2659,14 +2662,14 @@ function New-PEMedia {
$OSCDIMGPath = "$adkPath`Assessment and Deployment Kit\Deployment Tools\arm64\Oscdimg" $OSCDIMGPath = "$adkPath`Assessment and Deployment Kit\Deployment Tools\arm64\Oscdimg"
} }
$OSCDIMG = "$OSCDIMGPath\oscdimg.exe" $OSCDIMG = "$OSCDIMGPath\oscdimg.exe"
WriteLog "Creating WinPE ISO at $FFUDevelopmentPath\$WinPEISOName" 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 # & "$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($WindowsArch -eq 'x64'){
$OSCDIMGArgs = "-m -o -u2 -udfver102 -bootdata:2`#p0,e,b`"$OSCDIMGPath\etfsboot.com`"`#pEF,e,b`"$OSCDIMGPath\Efisys_noprompt.bin`" `"$WinPEFFUPath\media`" `"$FFUDevelopmentPath\$WinPEISOName`"" $OSCDIMGArgs = "-m -o -u2 -udfver102 -bootdata:2`#p0,e,b`"$OSCDIMGPath\etfsboot.com`"`#pEF,e,b`"$OSCDIMGPath\Efisys_noprompt.bin`" `"$WinPEFFUPath\media`" `"$WinPEISOFile`""
} }
elseif($WindowsArch -eq 'arm64'){ elseif($WindowsArch -eq 'arm64'){
$OSCDIMGArgs = "-m -o -u2 -udfver102 -bootdata:1`#pEF,e,b`"$OSCDIMGPath\Efisys_noprompt.bin`" `"$WinPEFFUPath\media`" `"$FFUDevelopmentPath\$WinPEISOName`"" $OSCDIMGArgs = "-m -o -u2 -udfver102 -bootdata:1`#pEF,e,b`"$OSCDIMGPath\Efisys_noprompt.bin`" `"$WinPEFFUPath\media`" `"$WinPEISOFile`""
} }
Invoke-Process $OSCDIMG $OSCDIMGArgs Invoke-Process $OSCDIMG $OSCDIMGArgs
WriteLog "ISO created successfully" WriteLog "ISO created successfully"
@@ -1,21 +0,0 @@
rd c:\FFUDevelopment\WinPE /S /Q
cmd /c copype arm64 c:\FFUDevelopment\WinPE
Dism /Mount-Image /ImageFile:"c:\FFUDevelopment\WinPE\media\sources\boot.wim" /Index:1 /MountDir:"c:\FFUDevelopment\WinPE\mount"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\WinPE-WMI.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\en-us\WinPE-WMI_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\WinPE-NetFX.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\en-us\WinPE-NetFX_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\WinPE-Scripting.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\en-us\WinPE-Scripting_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\WinPE-PowerShell.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\en-us\WinPE-PowerShell_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\WinPE-StorageWMI.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\en-us\WinPE-StorageWMI_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\WinPE-DismCmdlets.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\arm64\WinPE_OCs\en-us\WinPE-DismCmdlets_en-us.cab"
xcopy "C:\FFUDevelopment\WinPEDeployFFUFilesVM" c:\FFUDevelopment\WinPE\mount /Y /E
REM If you need to add drivers, remove the REM from the below line and change the /Driver:Path to a folder of drivers
REM dism /image:C:\FFUDevelopment\WinPE\mount /Add-Driver /Driver:<Path to Drivers folder e.g c:\drivers> /Recurse
Dism /Unmount-Image /MountDir:c:\FFUDevelopment\WinPE\mount /Commit
MakeWinPEMedia /ISO /F c:\FFUDevelopment\WinPE "c:\FFUDevelopment\WinPE_FFU_Deploy_VM_arm64.iso"
rd c:\FFUDevelopment\WinPE /S /Q
@@ -1,21 +0,0 @@
rd c:\FFUDevelopment\WinPE /S /Q
cmd /c copype amd64 c:\FFUDevelopment\WinPE
Dism /Mount-Image /ImageFile:"c:\FFUDevelopment\WinPE\media\sources\boot.wim" /Index:1 /MountDir:"c:\FFUDevelopment\WinPE\mount"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-WMI.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-WMI_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-NetFX.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-NetFX_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-Scripting.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-Scripting_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-PowerShell.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-PowerShell_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-StorageWMI.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-StorageWMI_en-us.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-DismCmdlets.cab"
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-DismCmdlets_en-us.cab"
xcopy "C:\FFUDevelopment\WinPEDeployFFUFilesVM" c:\FFUDevelopment\WinPE\mount /Y /E
REM If you need to add drivers, remove the REM from the below line and change the /Driver:Path to a folder of drivers
REM dism /image:C:\FFUDevelopment\WinPE\mount /Add-Driver /Driver:<Path to Drivers folder e.g c:\drivers> /Recurse
Dism /Unmount-Image /MountDir:c:\FFUDevelopment\WinPE\mount /Commit
MakeWinPEMedia /ISO /F c:\FFUDevelopment\WinPE "c:\FFUDevelopment\WinPE_FFU_Deploy_VM_amd64.iso"
rd c:\FFUDevelopment\WinPE /S /Q
+54 -73
View File
@@ -14,9 +14,39 @@ function Get-USBDrive(){
return $USBDriveLetter return $USBDriveLetter
} }
# function Get-HardDrive(){
# $DeviceID = (Get-WmiObject -Class 'Win32_DiskDrive' | Where-Object {$_.MediaType -eq 'Fixed hard disk media' -and $_.Model -ne 'Microsoft Virtual Disk'}).DeviceID
# return $DeviceID
# }
function Get-HardDrive(){ function Get-HardDrive(){
$DeviceID = (Get-WmiObject -Class 'Win32_DiskDrive' | Where-Object {$_.MediaType -eq 'Fixed hard disk media' -and $_.Model -ne 'Microsoft Virtual Disk'}).DeviceID $SystemInfo = Get-WmiObject -Class 'Win32_ComputerSystem'
return $DeviceID $Manufacturer = $SystemInfo.Manufacturer
$Model = $SystemInfo.Model
WriteLog "Device Manufacturer: $Manufacturer"
WriteLog "Device Model: $Model"
WriteLog 'Getting Hard Drive info'
if ($Manufacturer -eq 'Microsoft Corporation' -and $Model -eq 'Virtual Machine'){
WriteLog 'Running in a Hyper-V VM. Getting virtual disk on Index 0 and SCSILogicalUnit 0'
$DiskDrive = Get-WmiObject -Class 'Win32_DiskDrive' | Where-Object {$_.MediaType -eq 'Fixed hard disk media' `
-and $_.Model -eq 'Microsoft Virtual Disk' `
-and $_.Index -eq 0 `
-and $_.SCSILogicalUnit -eq 0
}
}
else{
WriteLog 'Not running in a VM. Getting physical disk drive'
$DiskDrive = Get-WmiObject -Class 'Win32_DiskDrive' | Where-Object {$_.MediaType -eq 'Fixed hard disk media' -and $_.Model -ne 'Microsoft Virtual Disk'}
}
$DeviceID = $DiskDrive.DeviceID
$BytesPerSector = $Diskdrive.BytesPerSector
# Create a custom object to return both values
$result = New-Object PSObject -Property @{
DeviceID = $DeviceID
BytesPerSector = $BytesPerSector
}
return $result
} }
function WriteLog($LogText){ function WriteLog($LogText){
@@ -122,35 +152,17 @@ WriteLog 'Begin Logging'
WriteLog "Script version: $version" WriteLog "Script version: $version"
#Find PhysicalDrive #Find PhysicalDrive
$PhysicalDeviceID = Get-HardDrive # $PhysicalDeviceID = Get-HardDrive
$hardDrive = Get-HardDrive
$PhysicalDeviceID = $hardDrive.DeviceID
$BytesPerSector = $hardDrive.BytesPerSector
WriteLog "Physical BytesPerSector is $BytesPerSector"
WriteLog "Physical DeviceID is $PhysicalDeviceID" WriteLog "Physical DeviceID is $PhysicalDeviceID"
#Parse DiskID Number #Parse DiskID Number
$DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1,1) $DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1,1)
WriteLog "DiskID is $DiskID" WriteLog "DiskID is $DiskID"
#COMMENT THIS WHOLE BLOCK OUT ONCE FFUPROVIDER FIX IS IN
# #Modify diskpart answer files if DiskID not 0
# # $UEFIFFUPartitions = 'x:\CreateUEFI-FFU-Partitions.txt'
# $ExtendPartition = 'x:\ExtendPartition-UEFI.txt'
# If ($DiskID -ne '0'){
# WriteLog 'DiskID is not 0. Need to modify diskpart answer files'
# # try {
# # Set-DiskpartAnswerFiles $UEFIFFUPartitions $DiskID
# # }
# # catch {
# # WriteLog "Modifying $UEFIFFUPartitions failed with error: $_"
# # }
# try {
# Set-DiskpartAnswerFiles $ExtendPartition $DiskID
# }
# catch {
# WriteLog "Modifying $ExtendPartition failed with error: $_"
# }
# }
#Find FFU Files #Find FFU Files
[array]$FFUFiles = @(Get-ChildItem -Path $USBDrive*.ffu) [array]$FFUFiles = @(Get-ChildItem -Path $USBDrive*.ffu)
$FFUCount = $FFUFiles.Count $FFUCount = $FFUFiles.Count
@@ -426,8 +438,6 @@ If (Test-Path -Path $Drivers)
#Partition drive #Partition drive
Writelog 'Clean Disk' Writelog 'Clean Disk'
#Start-Process -FilePath diskpart.exe -ArgumentList "/S $UEFIFFUPartitions" -Wait -ErrorAction Stop | Out-File $Logfile -Append
#Invoke-Process diskpart.exe "/S $UEFIFFUPartitions"
try { try {
$Disk = Get-Disk -Number $DiskID $Disk = Get-Disk -Number $DiskID
if ($Disk.PartitionStyle -ne "RAW") { if ($Disk.PartitionStyle -ne "RAW") {
@@ -448,58 +458,39 @@ WriteLog "Running command dism /apply-ffu /ImageFile:$FFUFileToInstall /ApplyDri
dism /apply-ffu /ImageFile:$FFUFileToInstall /ApplyDrive:$PhysicalDeviceID dism /apply-ffu /ImageFile:$FFUFileToInstall /ApplyDrive:$PhysicalDeviceID
$recoveryPartition = Get-Partition -Disk $Disk | Where-Object PartitionNumber -eq 4 $recoveryPartition = Get-Partition -Disk $Disk | Where-Object PartitionNumber -eq 4
if ($recoveryPartition) { if ($recoveryPartition) {
WriteLog 'Setting recovery partition attributes'
$diskpartScript = @( $diskpartScript = @(
"SELECT DISK $($Disk.Number)", "SELECT DISK $($Disk.Number)",
"SELECT PARTITION $($recoveryPartition.PartitionNumber)", "SELECT PARTITION $($recoveryPartition.PartitionNumber)",
"GPT ATTRIBUTES=0x8000000000000001", "GPT ATTRIBUTES=0x8000000000000001",
"EXIT" "EXIT"
) )
$diskpartScript | diskpart.exe $diskpartScript | diskpart.exe | Out-Null
WriteLog 'Setting recovery partition attributes complete'
} }
if($LASTEXITCODE -eq 0){ if($LASTEXITCODE -eq 0){
WriteLog 'Successfully applied FFU' WriteLog 'Successfully applied FFU'
} }
elseif($LASTEXITCODE -eq 1393){
WriteLog "Failed to apply FFU - LastExitCode = $LastExitCode"
WriteLog "This is likely due to a mismatched LogicalSectorByteSize"
WriteLog "BytesPerSector value from Win32_Diskdrive is $BytesPerSector"
if ($BytesPerSector -eq 4096){
WriteLog "The FFU build process by default uses a 512 LogicalSectorByteSize. Rebuild the FFU by adding -LogicalSectorByteSize 4096 to the command line"
}
elseif($BytesPerSector -eq 512){
WriteLog "This FFU was likely built with a LogicalSectorByteSize of 4096. Rebuild the FFU by adding -LogicalSectorByteSize 512 to the command line"
}
#Copy DISM log to USBDrive
invoke-process xcopy.exe "X:\Windows\logs\dism\dism.log $USBDrive /Y"
exit
}
else{ else{
Writelog "Failed to apply FFU - LastExitCode = $LASTEXITCODE also check dism.log on the USB drive for more info" Writelog "Failed to apply FFU - LastExitCode = $LASTEXITCODE also check dism.log on the USB drive for more info"
#Copy DISM log to USBDrive #Copy DISM log to USBDrive
invoke-process xcopy.exe "X:\Windows\logs\dism\dism.log $USBDrive /Y" invoke-process xcopy.exe "X:\Windows\logs\dism\dism.log $USBDrive /Y"
exit exit
} }
#Remove recovery partition - this is needed in order to extend the Windows partition so it uses the full disk size. If dism /optimize-ffu worked, this wouldn't be needed
# $disk = get-disk -Number $DiskID
# $RecoveryPartition = $disk | get-partition | Where-Object {$_.type -eq 'Recovery'}
# if ($RecoveryPartition){
# $RecoveryPartitionNumber = $RecoveryPartition.PartitionNumber
# if ($RecoveryPartitionNumber -eq 4){
# try {
# WriteLog 'Removing recovery partition'
# Remove-partition -DiskNumber $DiskID -PartitionNumber $RecoveryPartitionNumber -Confirm:$false
# }
# catch {
# WriteLog 'Error removing recovery partition, exiting'
# throw $_
# }
# }
# else{
# WriteLog 'Recovery partition not partition 4. Script will exit. Please create the FFU with the recovery partition as the last partition. This is the default and recommended way.'
# exit
# }
# }
#COMMENT THIS WHOLE BLOCK OUT AFTER FFUPROVIDER FIX IS IN
# # Extend Windows partition and create recovery partition
# Writelog 'Extending Windows partition'
# Invoke-Process diskpart.exe "/S $ExtendPartition"
# if($LASTEXITCODE -eq 0){
# WriteLog 'Successfully extended Windows partition and created recovery partition'
# }
# else{
# Writelog "Failed to extend Windows partition and/or create recovery partition - LastExitCode = $LASTEXITCODE"
# }
#UNCOMMENT THIS AFTER FFUPROVIDER FIX IS IN
# Set W: drive letter to Windows partition
Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object PartitionNumber -eq 3 | Set-Partition -NewDriveLetter W Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object PartitionNumber -eq 3 | Set-Partition -NewDriveLetter W
#Copy modified WinRE if folder exists, else copy inbox WinRE #Copy modified WinRE if folder exists, else copy inbox WinRE
@@ -515,16 +506,6 @@ If (Test-Path -Path $WinRE)
Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object Type -eq Recovery | Remove-PartitionAccessPath -AccessPath R: Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object Type -eq Recovery | Remove-PartitionAccessPath -AccessPath R:
WriteLog 'Registering location of recovery tools succeeded' WriteLog 'Registering location of recovery tools succeeded'
} }
# else
# {
# WriteLog 'Copying default WinRE to Recovery directory'
# Invoke-Process xcopy.exe "/h W:\Windows\System32\Recovery\Winre.wim R:\Recovery\WindowsRE\ /Y"
# WriteLog 'Copying WinRE to Recovery directory succeeded'
# WriteLog 'Registering location of recovery tools'
# Invoke-process W:\Windows\System32\Reagentc.exe "/Setreimage /Path R:\Recovery\WindowsRE /Target W:\Windows"
# WriteLog 'Registering location of recovery tools succeeded'
# }
#Autopilot JSON #Autopilot JSON
If ($APFileToInstall){ If ($APFileToInstall){
WriteLog "Copying $APFileToInstall to W:\windows\provisioning\autopilot" WriteLog "Copying $APFileToInstall to W:\windows\provisioning\autopilot"
@@ -1,10 +0,0 @@
select disk 0
select partition 3
Assign letter="W"
shrink minimum=1000
create partition primary
format quick fs=ntfs label="Recovery"
assign letter="R"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001
exit
@@ -1,622 +0,0 @@
function Get-USBDrive(){
$USBDriveLetter = (Get-Volume | Where-Object {$_.DriveType -eq 'Removable' -and $_.FileSystemType -eq 'NTFS'}).DriveLetter
if ($null -eq $USBDriveLetter){
#Must be using a fixed USB drive - difficult to grab drive letter from win32_diskdrive. Assume user followed instructions and used Deploy as the friendly name for partition
$USBDriveLetter = (Get-Volume | Where-Object {$_.DriveType -eq 'Fixed' -and $_.FileSystemType -eq 'NTFS' -and $_.FileSystemLabel -eq 'Deploy'}).DriveLetter
#If we didn't get the drive letter, stop the script.
if ($null -eq $USBDriveLetter){
WriteLog 'Cannot find USB drive letter - most likely using a fixed USB drive. Name the 2nd partition with the FFU files as Deploy so the script can grab the drive letter. Exiting'
Exit
}
}
$USBDriveLetter = $USBDriveLetter + ":\"
return $USBDriveLetter
}
# function Get-HardDrive(){
# $DeviceID = (Get-WmiObject -Class 'Win32_DiskDrive' | Where-Object {$_.MediaType -eq 'Fixed hard disk media' -and $_.Model -ne 'Microsoft Virtual Disk'}).DeviceID
# return $DeviceID
# }
function Get-HardDrive(){
$DiskDrive = Get-WmiObject -Class 'Win32_DiskDrive' | Where-Object {$_.MediaType -eq 'Fixed hard disk media' -and $_.Model -eq 'Microsoft Virtual Disk'}
$DeviceID = $DiskDrive.DeviceID
$BytesPerSector = $Diskdrive.BytesPerSector
# Create a custom object to return both values
$result = New-Object PSObject -Property @{
DeviceID = $DeviceID
BytesPerSector = $BytesPerSector
}
return $result
}
function WriteLog($LogText){
Add-Content -path $LogFile -value "$((Get-Date).ToString()) $LogText"
}
function Set-DiskpartAnswerFiles($DiskpartFile,$DiskID){
(Get-Content $DiskpartFile).Replace('disk 0', "disk $DiskID") | Set-Content -Path $DiskpartFile
}
function Set-Computername($computername){
[xml]$xml = Get-Content $UnattendFile
if($xml.unattend.settings.component.Count -ge 2){
#Assumes that Computername is the first component element
$xml.unattend.settings.component[0].ComputerName = $computername
}else{
$xml.unattend.settings.component.ComputerName = $computername
}
$xml.Save($UnattendFile)
return $computername
}
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 = $false;
}
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 - check scriptlog.txt on the USB drive for more info'
throw $_
} finally {
Remove-Item -Path $stdOutTempFile, $stdErrTempFile -Force -ErrorAction Ignore
}
}
# This function can be used in instances where battery level might matter (e.g. installing firmware for Surface). The problem is that WinPE doesn't have
# a driver for the battery installed, so you'll need to inject drivers, which can be tricky because just injecting the battery driver might not be enough,
# you might also need other drivers that the battery driver is dependent on.
# function Get-Battery(){
# while (($BattLev = (Get-CimInstance win32_battery).EstimatedChargeRemaining) -lt "35")
# {
# WriteLog "Battery is currently at $BattLev`%. Waiting for 35`% to proceed..."
# Write-Host "Battery is currently at $BattLev`%. Waiting for 35`% to proceed..."
# Start-Sleep 60
# }
# WriteLog "Battery level is $BattLev `%, which is greater than 35'% applying FFU"
# Write-Host "Battery level is $BattLev `%, which is greater than 35'% applying FFU"
# }
#Get USB Drive and create log file
$LogFileName = 'ScriptLog.txt'
$USBDrive = Get-USBDrive
New-item -Path $USBDrive -Name $LogFileName -ItemType "file" -Force | Out-Null
$LogFile = $USBDrive + $LogFilename
$version = '2309.2'
WriteLog 'Begin Logging'
WriteLog "Script version: $version"
#Find PhysicalDrive
$hardDrive = Get-HardDrive
# $PhysicalDeviceID = $hardDrive.DeviceID
$BytesPerSector = $hardDrive.BytesPerSector
# WriteLog "Physical DeviceID is $PhysicalDeviceID"
# WriteLog "Physical BytesPerSector is $BytesPerSector"
$PhysicalDeviceID = '\\.\PHYSICALDRIVE0'
WriteLog "Physical DeviceID is $PhysicalDeviceID"
#Parse DiskID Number
# $DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1,1)
# WriteLog "DiskID is $DiskID"
$DiskID = '0'
WriteLog "DiskID is $DiskID"
#COMMENT THIS WHOLE BLOCK OUT ONCE FFUPROVIDER FIX IS IN
#Modify diskpart answer files if DiskID not 0
# $UEFIFFUPartitions = 'x:\CreateUEFI-FFU-Partitions.txt'
$ExtendPartition = 'x:\ExtendPartition-UEFI.txt'
If ($DiskID -ne '0'){
WriteLog 'DiskID is not 0. Need to modify diskpart answer files'
# try {
# Set-DiskpartAnswerFiles $UEFIFFUPartitions $DiskID
# }
# catch {
# WriteLog "Modifying $UEFIFFUPartitions failed with error: $_"
# }
try {
Set-DiskpartAnswerFiles $ExtendPartition $DiskID
}
catch {
WriteLog "Modifying $ExtendPartition failed with error: $_"
}
}
#Find FFU Files
[array]$FFUFiles = @(Get-ChildItem -Path $USBDrive*.ffu)
$FFUCount = $FFUFiles.Count
#If multiple FFUs found, ask which to install
If ($FFUCount -gt 1) {
WriteLog "Found $FFUCount FFU Files"
$array = @()
for($i=0;$i -le $FFUCount -1;$i++){
$Properties = [ordered]@{Number = $i + 1 ; FFUFile = $FFUFiles[$i].FullName}
$array += New-Object PSObject -Property $Properties
}
$array | Format-Table -AutoSize -Property Number, FFUFile
do {
try {
$var = $true
[int]$FFUSelected = Read-Host 'Enter the FFU number to install'
$FFUSelected = $FFUSelected -1
}
catch {
Write-Host 'Input was not in correct format. Please enter a valid FFU number'
$var = $false
}
} until (($FFUSelected -le $FFUCount -1) -and $var)
$FFUFileToInstall = $array[$FFUSelected].FFUFile
WriteLog "$FFUFileToInstall was selected"
}
elseif ($FFUCount -eq 1) {
WriteLog "Found $FFUCount FFU File"
$FFUFileToInstall = $FFUFiles[0].FullName
WriteLog "$FFUFileToInstall will be installed"
}
else {
Writelog 'No FFU files found'
Write-Host 'No FFU files found'
Exit
}
#FindAP
$APFolder = $USBDrive + "Autopilot\"
If (Test-Path -Path $APFolder){
[array]$APFiles = @(Get-ChildItem -Path $APFolder*.json)
$APFilesCount = $APFiles.Count
if ($APFilesCount -ge 1){
$autopilot = $true
}
}
#FindPPKG
$PPKGFolder = $USBDrive + "PPKG\"
if (Test-Path -Path $PPKGFolder){
[array]$PPKGFiles = @(Get-ChildItem -Path $PPKGFolder*.ppkg)
$PPKGFilesCount = $PPKGFiles.Count
if ($PPKGFilesCount -ge 1){
$PPKG = $true
}
}
#FindUnattend
$UnattendFolder = $USBDrive + "unattend\"
$UnattendFilePath = $UnattendFolder + "unattend.xml"
$UnattendPrefixPath = $UnattendFolder + "prefixes.txt"
If (Test-Path -Path $UnattendFilePath){
$UnattendFile = Get-ChildItem -Path $UnattendFilePath
If ($UnattendFile){
$Unattend = $true
}
}
If (Test-Path -Path $UnattendPrefixPath){
$UnattendPrefixFile = Get-ChildItem -Path $UnattendPrefixPath
If ($UnattendPrefixFile){
$UnattendPrefix = $true
}
}
#Ask for device name if unattend exists
if ($Unattend -and $UnattendPrefix){
Writelog 'Unattend file found with prefixes.txt. Getting prefixes.'
$UnattendPrefixes = @(Get-content $UnattendPrefixFile)
$UnattendPrefixCount = $UnattendPrefixes.Count
If ($UnattendPrefixCount -gt 1) {
WriteLog "Found $UnattendPrefixCount Prefixes"
$array = @()
for($i=0;$i -le $UnattendPrefixCount -1;$i++){
$Properties = [ordered]@{Number = $i + 1 ; DeviceNamePrefix = $UnattendPrefixes[$i]}
$array += New-Object PSObject -Property $Properties
}
$array | Format-Table -AutoSize -Property Number, DeviceNamePrefix
do {
try {
$var = $true
[int]$PrefixSelected = Read-Host 'Enter the prefix number to use for the device name'
$PrefixSelected = $PrefixSelected -1
}
catch {
Write-Host 'Input was not in correct format. Please enter a valid prefix number'
$var = $false
}
} until (($PrefixSelected -le $UnattendPrefixCount -1) -and $var)
$PrefixToUse = $array[$PrefixSelected].DeviceNamePrefix
WriteLog "$PrefixToUse was selected"
}
elseif ($UnattendPrefixCount -eq 1) {
WriteLog "Found $UnattendPrefixCount Prefix"
$PrefixToUse = $UnattendPrefixes[0]
WriteLog "Will use $PrefixToUse as device name prefix"
}
#Get serial number to append. This can make names longer than 15 characters. Trim any leading or trailing whitespace
$serial = (Get-CimInstance -ClassName win32_bios).SerialNumber.Trim()
#Combine prefix with serial
$computername = $PrefixToUse + $serial
#If computername is longer than 15 characters, reduce to 15. Sysprep/unattend doesn't like ComputerName being longer than 15 characters even though Windows accepts it
If ($computername.Length -gt 15){
$computername = $computername.substring(0,15)
}
$computername = Set-Computername($computername)
Writelog "Computer name set to $computername"
}
elseif($Unattend){
Writelog 'Unattend file found with no prefixes.txt, asking for name'
[string]$computername = Read-Host 'Enter device name'
Set-Computername($computername)
Writelog "Computer name set to $computername"
}
else {
WriteLog 'No unattend folder found. Device name will be set via PPKG, AP JSON, or default OS name.'
}
#If both AP and PPKG folder found with files, ask which to use.
If($autopilot -eq $true -and $PPKG -eq $true){
WriteLog 'Both PPKG and Autopilot json files found'
Write-Host 'Both Autopilot JSON files and Provisioning packages were found.'
do {
try {
$var = $true
[int]$APorPPKG = Read-Host 'Enter 1 for Autopilot or 2 for Provisioning Package'
}
catch {
Write-Host 'Incorrect value. Please enter 1 for Autopilot or 2 for Provisioning Package'
$var = $false
}
} until (($APorPPKG -gt 0 -and $APorPPKG -lt 3) -and $var)
If ($APorPPKG -eq 1){
$PPKG = $false
}
else{
$autopilot = $false
}
}
#If multiple AP json files found, ask which to install
If ($APFilesCount -gt 1 -and $autopilot -eq $true) {
WriteLog "Found $APFilesCount Autopilot json Files"
$array = @()
for($i=0;$i -le $APFilesCount -1;$i++){
$Properties = [ordered]@{Number = $i + 1 ; APFile = $APFiles[$i].FullName; APFileName = $APFiles[$i].Name}
$array += New-Object PSObject -Property $Properties
}
$array | Format-Table -AutoSize -Property Number, APFileName
do {
try {
$var = $true
[int]$APFileSelected = Read-Host 'Enter the AP json file number to install'
$APFileSelected = $APFileSelected - 1
}
catch {
Write-Host 'Input was not in correct format. Please enter a valid AP json file number'
$var = $false
}
} until (($APFileSelected -le $APFilesCount -1) -and $var)
$APFileToInstall = $array[$APFileSelected].APFile
$APFileName = $array[$APFileSelected].APFileName
WriteLog "$APFileToInstall was selected"
}
elseif ($APFilesCount -eq 1 -and $autopilot -eq $true) {
WriteLog "Found $APFilesCount AP File"
$APFileToInstall = $APFiles[0].FullName
$APFileName = $APFiles[0].Name
WriteLog "$APFileToInstall will be copied"
}
else {
Writelog 'No AP files found or AP was not selected'
}
#If multiple PPKG files found, ask which to install
If ($PPKGFilesCount -gt 1 -and $PPKG -eq $true) {
WriteLog "Found $PPKGFilesCount PPKG Files"
$array = @()
for($i=0;$i -le $PPKGFilesCount -1;$i++){
$Properties = [ordered]@{Number = $i + 1 ; PPKGFile = $PPKGFiles[$i].FullName; PPKGFileName = $PPKGFiles[$i].Name}
$array += New-Object PSObject -Property $Properties
}
$array | Format-Table -AutoSize -Property Number, PPKGFileName
do {
try {
$var = $true
[int]$PPKGFileSelected = Read-Host 'Enter the PPKG file number to install'
$PPKGFileSelected = $PPKGFileSelected - 1
}
catch {
Write-Host 'Input was not in correct format. Please enter a valid PPKG file number'
$var = $false
}
} until (($PPKGFileSelected -le $PPKGFilesCount -1) -and $var)
$PPKGFileToInstall = $array[$PPKGFileSelected].PPKGFile
WriteLog "$PPKGFileToInstall was selected"
}
elseif ($PPKGFilesCount -eq 1 -and $PPKG -eq $true) {
WriteLog "Found $PPKGFilesCount PPKG File"
$PPKGFileToInstall = $PPKGFiles[0].FullName
WriteLog "$PPKGFileToInstall will be used"
}
else {
Writelog 'No PPKG files found or PPKG not selected.'
}
#Find Drivers
$Drivers = $USBDrive + "Drivers"
If (Test-Path -Path $Drivers)
{
#Check if multiple driver folders found, if so, just select one folder to save time/space
$DriverFolders = Get-ChildItem -Path $Drivers
$DriverFoldersCount = $DriverFolders.count
If ($DriverFoldersCount -gt 1)
{
WriteLog "Found $DriverFoldersCount driver folders"
$array = @()
for($i=0; $i -le $DriverFoldersCount -1; $i++){
$Properties = [ordered]@{Number = $i + 1; Drivers = $DriverFolders[$i].FullName}
$array += New-Object PSObject -Property $Properties
}
$array | Format-Table -AutoSize -Property Number, Drivers
do {
try {
$var = $true
[int]$DriversSelected = Read-Host 'Enter the set of drivers to install'
$DriversSelected = $DriversSelected - 1
}
catch {
Write-Host 'Input was not in correct format. Please enter a valid driver folder number'
$var = $false
}
} until (($DriversSelected -le $DriverFoldersCount -1) -and $var)
$Drivers = $array[$DriversSelected].Drivers
WriteLog "$Drivers was selected"
}
elseif ($DriverFoldersCount -eq 1) {
WriteLog "Found $DriverFoldersCount driver folder"
$Drivers = $DriverFolders.FullName
WriteLog "$Drivers will be installed"
}
else {
Writelog 'No driver folders found'
}
}
#If you want to enable battery level checking, uncomment the line below as well as the Get-Battery function near the top of the script
#Get-Battery
#Partition drive
Writelog 'Clean Disk'
#Start-Process -FilePath diskpart.exe -ArgumentList "/S $UEFIFFUPartitions" -Wait -ErrorAction Stop | Out-File $Logfile -Append
#Invoke-Process diskpart.exe "/S $UEFIFFUPartitions"
try {
$Disk = Get-Disk -Number $DiskID
$Disk | clear-disk -RemoveData -RemoveOEM -Confirm:$false
}
catch {
WriteLog 'Cleaning disk failed. Exiting'
throw $_
}
Writelog 'Cleaning Disk succeeded'
#Apply FFU
WriteLog "Applying FFU to $PhysicalDeviceID"
WriteLog "Running command dism /apply-ffu /ImageFile:$FFUFileToInstall /ApplyDrive:$PhysicalDeviceID"
#In order for Applying Image progress bar to show up, need to call dism directly. Might be a better way to handle, but must have progress bar show up on screen.
dism /apply-ffu /ImageFile:$FFUFileToInstall /ApplyDrive:$PhysicalDeviceID
if($LASTEXITCODE -eq 0){
WriteLog 'Successfully applied FFU'
}
elseif($LASTEXITCODE -eq 1393){
WriteLog "Failed to apply FFU - LastExitCode = $LastExitCode"
WriteLog "This is likely due to a mismatched LogicalSectorByteSize"
WriteLog "BytesPerSector value from Win32_Diskdrive is $BytesPerSector"
if ($BytesPerSector -eq 4096){
WriteLog "The FFU build process by default uses a 512 LogicalSectorByteSize. Rebuild the FFU by adding -LogicalSectorByteSize 4096 to the command line"
}
elseif($BytesPerSector -eq 512){
WriteLog "This FFU was likely built with a LogicalSectorByteSize of 4096. Rebuild the FFU by adding -LogicalSectorByteSize 512 to the command line"
}
#Copy DISM log to USBDrive
invoke-process xcopy.exe "X:\Windows\logs\dism\dism.log $USBDrive /Y"
exit
}
else{
Writelog "Failed to apply FFU - LastExitCode = $LASTEXITCODE also check dism.log on the USB drive for more info"
#Copy DISM log to USBDrive
invoke-process xcopy.exe "X:\Windows\logs\dism\dism.log $USBDrive /Y"
exit
}
#Remove recovery partition - this is needed in order to extend the Windows partition so it uses the full disk size. If dism /optimize-ffu worked, this wouldn't be needed
# $disk = get-disk -Number $DiskID
# $RecoveryPartition = $disk | get-partition | Where-Object {$_.type -eq 'Recovery'}
# if ($RecoveryPartition){
# $RecoveryPartitionNumber = $RecoveryPartition.PartitionNumber
# if ($RecoveryPartitionNumber -eq 4){
# try {
# WriteLog 'Removing recovery partition'
# Remove-partition -DiskNumber $DiskID -PartitionNumber $RecoveryPartitionNumber -Confirm:$false
# }
# catch {
# WriteLog 'Error removing recovery partition, exiting'
# throw $_
# }
# }
# else{
# WriteLog 'Recovery partition not partition 4. Script will exit. Please create the FFU with the recovery partition as the last partition. This is the default and recommended way.'
# exit
# }
# }
#COMMENT THIS WHOLE BLOCK OUT AFTER FFUPROVIDER FIX IS IN
# Extend Windows partition and create recovery partition
Writelog 'Extending Windows partition'
Invoke-Process diskpart.exe "/S $ExtendPartition"
if($LASTEXITCODE -eq 0){
WriteLog 'Successfully extended Windows partition and created recovery partition'
}
else{
Writelog "Failed to extend Windows partition and/or create recovery partition - LastExitCode = $LASTEXITCODE"
}
#UNCOMMENT THIS AFTER FFUPROVIDER FIX IS IN
#Set W: drive letter to Windows partition
#Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object PartitionNumber -eq 3 | Set-Partition -NewDriveLetter W
#Copy modified WinRE if folder exists, else copy inbox WinRE
$WinRE = $USBDrive + "WinRE\winre.wim"
If (Test-Path -Path $WinRE)
{
WriteLog 'Copying modified WinRE to Recovery directory'
Invoke-Process xcopy.exe "/h $WinRE R:\Recovery\WindowsRE\ /Y"
WriteLog 'Copying WinRE to Recovery directory succeeded'
WriteLog 'Registering location of recovery tools'
Invoke-Process W:\Windows\System32\Reagentc.exe "/Setreimage /Path R:\Recovery\WindowsRE /Target W:\Windows"
WriteLog 'Registering location of recovery tools succeeded'
}
# else
# {
# WriteLog 'Copying default WinRE to Recovery directory'
# Invoke-Process xcopy.exe "/h W:\Windows\System32\Recovery\Winre.wim R:\Recovery\WindowsRE\ /Y"
# WriteLog 'Copying WinRE to Recovery directory succeeded'
# WriteLog 'Registering location of recovery tools'
# Invoke-process W:\Windows\System32\Reagentc.exe "/Setreimage /Path R:\Recovery\WindowsRE /Target W:\Windows"
# WriteLog 'Registering location of recovery tools succeeded'
# }
#Autopilot JSON
If ($APFileToInstall){
WriteLog "Copying $APFileToInstall to W:\windows\provisioning\autopilot"
Invoke-process xcopy.exe "$APFileToInstall W:\Windows\provisioning\autopilot\"
WriteLog "Copying $APFileToInstall to W:\windows\provisioning\autopilot succeeded"
# Rename file in W:\Windows\Provisioning\Autopilot to AutoPilotConfigurationFile.json
try {
Rename-Item -Path "W:\Windows\Provisioning\Autopilot\$APFileName" -NewName 'W:\Windows\Provisioning\Autopilot\AutoPilotConfigurationFile.json'
WriteLog "Renamed W:\Windows\Provisioning\Autopilot\$APFilename to W:\Windows\Provisioning\Autopilot\AutoPilotConfigurationFile.json"
}
catch{
Writelog "Copying $APFileToInstall to W:\windows\provisioning\autopilot failed with error: $_"
throw $_
}
}
#Apply PPKG
If ($PPKGFileToInstall){
try {
#Make sure to delete any existing PPKG on the USB drive
Get-Childitem -Path $USBDrive\*.ppkg | ForEach-Object {
Remove-item -Path $_.FullName
}
WriteLog "Copying $PPKGFileToInstall to $USBDrive"
Invoke-process xcopy.exe "$PPKGFileToInstall $USBDrive"
WriteLog "Copying $PPKGFileToInstall to $USBDrive succeeded"
}
catch{
Writelog "Copying $PPKGFileToInstall to $USBDrive failed with error: $_"
throw $_
}
}
#Set DeviceName
If ($computername){
try{
$PantherDir = 'w:\windows\panther'
If (Test-Path -Path $PantherDir){
Writelog "Copying $UnattendFile to $PantherDir"
Invoke-process xcopy "$UnattendFile $PantherDir /Y"
WriteLog "Copying $UnattendFile to $PantherDir succeeded"
}
else{
Writelog "$PantherDir doesn't exist, creating it"
New-Item -Path $PantherDir -ItemType Directory -Force
Writelog "Copying $UnattendFile to $PantherDir"
Invoke-Process xcopy.exe "$UnattendFile $PantherDir"
WriteLog "Copying $UnattendFile to $PantherDir succeeded"
}
}
catch{
WriteLog "Copying Unattend.xml to name device failed"
throw $_
}
}
#Add Drivers
#Some drivers can sometimes fail to copy and dism ends up with a non-zero error code. Invoke-process will throw and terminate in these instances.
If (Test-Path -Path $Drivers)
{
WriteLog 'Copying drivers'
Write-Warning 'Copying Drivers - dism will pop a window with no progress. This can take a few minutes to complete. This is done so drivers are logged to the scriptlog.txt file. Please be patient.'
Invoke-process dism.exe "/image:W:\ /Add-Driver /Driver:""$Drivers"" /Recurse"
WriteLog 'Copying drivers succeeded'
}
#Copy DISM log to USBDrive
WriteLog "Copying dism log to $USBDrive"
invoke-process xcopy "X:\Windows\logs\dism\dism.log $USBDrive /Y"
WriteLog "Copying dism log to $USBDrive succeeded"
@@ -1,10 +0,0 @@
select disk 0
select partition 3
Assign letter="W"
shrink minimum=1000
create partition primary
format quick fs=ntfs label="Recovery"
assign letter="R"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001
exit
@@ -1,5 +0,0 @@
wpeinit
powercfg /s 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
powershell -Noprofile -ExecutionPolicy Bypass -File x:\ApplyFFU.ps1
exit