diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 70ddff5..51a9c7a 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -3,26 +3,33 @@ $rand = get-random $VMName = "_FFU-$rand" $VMPath = "c:\VM\$VMName" $VHDPath = "$VMPath\$VMName.vhdx" -$ISOPath = "E:\software\ISOs\Windows\Windows 11\22H2\en-us_windows_11_consumer_editions_version_22h2_updated_jan_2023_x64_dvd_aafaf7fa.iso" +$ISOPath = "E:\software\ISOs\Windows\Windows 11\en-us_windows_11_consumer_editions_version_22h2_updated_feb_2023_x64_dvd_4fa87138.iso" $memory = 8GB $processors = 4 +$disksize = 30GB -# 0. Delete old VMs +# 0. Delete old VMs and remove old certs +$certPath = 'Cert:\LocalMachine\Shielded VM Local Certificates\' $vms = get-vm _ffu-* | ? {$_.state -ne 'running'} If($null -ne $vms){ Foreach ($vm in $vms){ - $OldVMName = $vm.VMName - Remove-VM -Name $vm.name -Force -ErrorAction SilentlyContinue - Remove-Item -Path "C:\VM\$OldVMName" -Force -Recurse -ErrorAction SilentlyContinue + $OldVMName = $vm.VMName + Remove-VM -Name $vm.name -Force -ErrorAction SilentlyContinue + Remove-Item -Path "C:\VM\$OldVMName" -Force -Recurse -ErrorAction SilentlyContinue + Remove-HgsGuardian -Name $OldVMName + $certs = Get-ChildItem -Path $certPath -Recurse | Where-Object { $_.Subject -like "*$OldVMName*" } + foreach ($cert in $Certs){ + Remove-item -Path $cert.PSPath -force + } } } # 1. Create Dynamic Hard Disk mkdir -Path $VMPath -Force -#New-VHD -Path $VHDPath -Fixed -SizeBytes 30GB -New-VHD -path $VHDPath -SizeBytes 128000000000 -LogicalSectorSizeBytes 512 -Dynamic +New-VHD -Path $VHDPath -Fixed -SizeBytes $disksize +#New-VHD -path $VHDPath -SizeBytes 128000000000 -LogicalSectorSizeBytes 512 -Dynamic # 2. Create VM # - Name: _FFU @@ -32,23 +39,22 @@ New-VHD -path $VHDPath -SizeBytes 128000000000 -LogicalSectorSizeBytes 512 -Dyna # - Networking: Not connected # - Connect to existing VHD: c:\VM\_FFU\ # - Mount ISO -New-VM -Name $VMName -Path $VMPath -MemoryStartupBytes $memory -VHDPath $VHDPath -Generation 2 +$VM = New-VM -Name $VMName -Path $VMPath -MemoryStartupBytes $memory -VHDPath $VHDPath -Generation 2 Set-VMProcessor -VMName $VMName -Count $processors Add-VMDvdDrive -VMName $VMName -Path $ISOPath $VMDVDDrive = Get-VMDvdDrive -VMName $VMName - -#Use for Win11 Set-VMFirmware -VMName $VMName -FirstBootDevice $VMDVDDrive -If(Get-HgsGuardian -Name 'Guardian'){ - Remove-HgsGuardian -Name 'Guardian' - Get-ChildItem -Path 'Cert:\LocalMachine\Shielded VM Local Certificates\' | Remove-Item -} -New-HgsGuardian -Name 'Guardian' -GenerateCertificates -$owner = get-hgsguardian -Name 'Guardian' + +#Configure TPM +New-HgsGuardian -Name $VMName -GenerateCertificates +$owner = get-hgsguardian -Name $VMName $kp = New-HgsKeyProtector -Owner $owner -AllowUntrustedRoot Set-VMKeyProtector -VMName $VMName -KeyProtector $kp.RawData Enable-VMTPM -VMName $VMName +#Connect to VM +vmconnect $VM.ComputerName $VMName + #Use if creating for MDT/SCCM Builds #Get-VM $VMName | Get-VMNetworkAdapter | Connect-VMNetworkAdapter -SwitchName "Intel(R) I350 Gigabit Network Connection - Virtual Switch" #$networkAdapter = Get-VMNetworkAdapter -VMName $VMName \ No newline at end of file diff --git a/FFUDevelopment/BuildWinPECaptureMedia.cmd b/FFUDevelopment/BuildWinPECaptureMedia.cmd index 6cd695d..ebb0651 100644 --- a/FFUDevelopment/BuildWinPECaptureMedia.cmd +++ b/FFUDevelopment/BuildWinPECaptureMedia.cmd @@ -1,20 +1,21 @@ -rd c:\WinPE /S /Q -md c:\WinPEOutput -cmd /c copype amd64 c:\WinPE -Dism /Mount-Image /ImageFile:"c:\WinPE\media\sources\boot.wim" /Index:1 /MountDir:"c:\WinPE\mount" -Dism /Add-Package /Image:"c:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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:\FFU Development\WinPECaptureFFUFiles" c:\WinPE\mount /Y /E -Dism /Unmount-Image /MountDir:c:\WinPE\mount /Commit -MakeWinPEMedia /ISO /F c:\WinPE "C:\WinPEOutput\WinPE_FFU_Capture.iso" +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\WinPECaptureFFUFiles" 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: /Recurse +Dism /Unmount-Image /MountDir:c:\FFUDevelopment\WinPE\mount /Commit +MakeWinPEMedia /ISO /F c:\FFUDevelopment\WinPE "c:\FFUDevelopment\WinPE_FFU_Capture.iso" diff --git a/FFUDevelopment/BuildWinPEDeploymentMedia.cmd b/FFUDevelopment/BuildWinPEDeploymentMedia.cmd index 4b57713..3054081 100644 --- a/FFUDevelopment/BuildWinPEDeploymentMedia.cmd +++ b/FFUDevelopment/BuildWinPEDeploymentMedia.cmd @@ -1,19 +1,20 @@ -rd c:\WinPE /S /Q -cmd /c copype amd64 C:\WinPE -Dism /Mount-Image /ImageFile:"C:\WinPE\media\sources\boot.wim" /Index:1 /MountDir:"C:\WinPE\mount" -Dism /Add-Package /Image:"C:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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" -REM Dism /image:"C:\WinPE\mount" /add-driver /Driver:C:\temp\drivers\LGO\Battery /recurse -xcopy "C:\FFU Development\WinPEDeployFFUFiles" c:\WinPE\mount /Y /E -Dism /Unmount-Image /MountDir:C:\WinPE\mount /Commit -MakeWinPEMedia /ISO /F C:\WinPE "C:\FFU Development\PE\WinPE_22H2.iso" \ No newline at end of file +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\WinPEDeployFFUFiles" 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: /Recurse +Dism /Unmount-Image /MountDir:c:\FFUDevelopment\WinPE\mount /Commit +MakeWinPEMedia /ISO /F c:\FFUDevelopment\WinPE "c:\FFUDevelopment\WinPE_FFU_Deploy.iso" \ No newline at end of file diff --git a/FFUDevelopment/BuildWinPEDeploymentMediaVM.cmd b/FFUDevelopment/BuildWinPEDeploymentMediaVM.cmd index c70e512..3c8602c 100644 --- a/FFUDevelopment/BuildWinPEDeploymentMediaVM.cmd +++ b/FFUDevelopment/BuildWinPEDeploymentMediaVM.cmd @@ -1,19 +1,20 @@ -rd c:\WinPE /S /Q -cmd /c copype amd64 C:\WinPE -Dism /Mount-Image /ImageFile:"C:\WinPE\media\sources\boot.wim" /Index:1 /MountDir:"C:\WinPE\mount" -Dism /Add-Package /Image:"C:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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:\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" -REM Dism /image:"C:\WinPE\mount" /add-driver /Driver:C:\temp\drivers\LGO\Battery /recurse -xcopy "C:\FFU Development\WinPEDeployFFUFilesVM" c:\WinPE\mount /Y /E -Dism /Unmount-Image /MountDir:C:\WinPE\mount /Commit -MakeWinPEMedia /ISO /F C:\WinPE "C:\FFU Development\PE\WinPE_21H2VM.iso" \ No newline at end of file +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: /Recurse +Dism /Unmount-Image /MountDir:c:\FFUDevelopment\WinPE\mount /Commit +MakeWinPEMedia /ISO /F c:\FFUDevelopment\WinPE "c:\FFUDevelopment\WinPE_FFU_Deploy_VM.iso" \ No newline at end of file diff --git a/FFUDevelopment/CreateOfficeISO.ps1 b/FFUDevelopment/CreateOfficeISO.ps1 new file mode 100644 index 0000000..4cee4c3 --- /dev/null +++ b/FFUDevelopment/CreateOfficeISO.ps1 @@ -0,0 +1,52 @@ +function Get-ODTURL { + + [String]$MSWebPage = Invoke-RestMethod 'https://www.microsoft.com/en-us/download/confirmation.aspx?id=49117' + + $MSWebPage | ForEach-Object { + if ($_ -match 'url=(https://.*officedeploymenttool.*\.exe)') { + $matches[1] + } + } +} + +$FFUDevPath = 'C:\FFUDevelopment' +$ODTUrl = Get-ODTURL +$ODTInstallFile = "$env:TEMP\odtsetup.exe" +Invoke-WebRequest -Uri $ODTUrl -OutFile $ODTInstallFile + +# Extract Office Deployment Tool +$ODTPath = "$FFUDevPath\Office" +Start-Process -FilePath $ODTInstallFile -ArgumentList "/extract:$ODTPath /quiet" -Wait + +# Run setup.exe with config.xml +$ConfigXml = "$FFUDevPath\Office\DownloadFFU.xml" +#Set-Location $ODTPath +Start-Process -FilePath "$FFUDevPath\Office\setup.exe" -ArgumentList "/download $ConfigXml" -Wait + +#Make Office ISO +Remove-Item -Path "$ODTPath\configuration*" -Force +$OSCDIMG = 'C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe' +$OfficeISO = "$FFUDevPath\office.iso" +Start-Process -FilePath $OSCDIMG -ArgumentList "-n -m $ODTPath $OfficeISO" -wait + +#Mount Office ISO to FFU VM +$VMS = get-vm _ffu-* | Where-Object {$_.state -eq 'running'} + +foreach ($VM in $VMs) { + # Check if DVD drive exists + $DVD = Get-VMDvdDrive -VMName $VM.Name + if ($DVD) { + # Attach ISO to existing DVD drive + Set-VMDvdDrive -VMName $VM.Name -Path $OfficeISO + } + else { + # Add DVD drive and attach ISO + Add-VMDvdDrive -VMName $VM.Name -Path $OfficeISO + } +} + +#Remove the Office Download and ODT +$OfficeDownloadPath = "$FFUDevPath\Office\Office" +Remove-Item -Path $OfficeDownloadPath -Recurse -Force +Remove-Item -Path "$ODTPath\setup.exe" + diff --git a/FFUDevelopment/Docs/BuildDeployFFU.docx b/FFUDevelopment/Docs/BuildDeployFFU.docx new file mode 100644 index 0000000..0466458 Binary files /dev/null and b/FFUDevelopment/Docs/BuildDeployFFU.docx differ diff --git a/FFUDevelopment/ModifyVMForCapture.ps1 b/FFUDevelopment/ModifyVMForCapture.ps1 new file mode 100644 index 0000000..8474168 --- /dev/null +++ b/FFUDevelopment/ModifyVMForCapture.ps1 @@ -0,0 +1,21 @@ +#Modify variables +$ISOPath = 'C:\FFUDevelopment\WinPE_FFU_Capture.iso' +$VMSwitchName = '*intel*' + +$vms = get-vm _ffu-* | ? {$_.state -ne 'running'} + + +If($null -ne $vms){ + Foreach ($vm in $vms){ + $VMName = $vm.name + $VMDVDDrive = Get-VMDvdDrive -VMName $VMName + Set-VMFirmware -VMName $VMName -FirstBootDevice $VMDVDDrive + Set-VMDvdDrive -VMName $VMName -Path $ISOPath + $VMSwitch = Get-VMSwitch -name $VMSwitchName + get-vm $VMName | Get-VMNetworkAdapter | Connect-VMNetworkAdapter -SwitchName $VMSwitch.Name + vmconnect $vm.ComputerName $VMName + } +} + + + diff --git a/FFUDevelopment/Office/DeployFFU.xml b/FFUDevelopment/Office/DeployFFU.xml new file mode 100644 index 0000000..6977fb3 --- /dev/null +++ b/FFUDevelopment/Office/DeployFFU.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FFUDevelopment/Office/DownloadFFU.xml b/FFUDevelopment/Office/DownloadFFU.xml new file mode 100644 index 0000000..d433f43 --- /dev/null +++ b/FFUDevelopment/Office/DownloadFFU.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FFUDevelopment/Office/InstallOfficeandSysprep.cmd b/FFUDevelopment/Office/InstallOfficeandSysprep.cmd index 1bc6810..d13072b 100644 --- a/FFUDevelopment/Office/InstallOfficeandSysprep.cmd +++ b/FFUDevelopment/Office/InstallOfficeandSysprep.cmd @@ -1,3 +1,4 @@ -d:\setup.exe /configure d:\FFU.xml +d:\setup.exe /configure d:\DeployFFU.xml taskkill /IM sysprep.exe +timeout /t 5 c:\windows\system32\sysprep\sysprep.exe /quiet /generalize /oobe \ No newline at end of file diff --git a/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 b/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 index 850389a..135e6cd 100644 --- a/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 +++ b/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 @@ -1,5 +1,5 @@ #Modify the net use path to map the W: drive to the location you want to copy the FFU file to -net use W: \\192.168.1.2\c$\temp /user:administrator p@ssw0rd +net use W: \\192.168.1.2\c$\FFUDevelopment /user:administrator p@ssw0rd $AssignDriveLetter = 'x:\AssignDriveLetter.txt' Start-Process -FilePath diskpart.exe -ArgumentList "/S $AssignDriveLetter" -Wait -ErrorAction Stop | Out-Null @@ -29,7 +29,8 @@ else{ } #If Office is installed, modify the file name of the FFU -$Office = Get-childitem -Path 'M:\Program Files\Microsoft Office' -ErrorAction SilentlyContinue | Out-Null +#$Office = Get-childitem -Path 'M:\Program Files\Microsoft Office' -ErrorAction SilentlyContinue | Out-Null +$Office = Get-childitem -Path 'M:\Program Files\Microsoft Office' if($Office){ $ffuFilePath = "W:\$Name`_$DisplayVersion`_$SKU`_Office`_$BuildDate.ffu" $dismArgs = "/capture-ffu /imagefile=$ffuFilePath /capturedrive=\\.\PhysicalDrive0 /name:$Name$DisplayVersion$SKU /Compress:Default" @@ -51,8 +52,6 @@ Remove-Variable Office reg unload "HKLM\FFU" Start-Process -FilePath dism.exe -ArgumentList $dismArgs -Wait -PassThru -ErrorAction Stop | Out-Null -$dismOptArgs = "/optimize-ffu /imagefile:$ffuFilePath" -Start-Process -FilePath dism.exe -ArgumentList $dismOptArgs -Wait -PassThru -ErrorAction Stop | Out-Null #Copy DISM log to Host xcopy X:\Windows\logs\dism\dism.log W:\ /Y | Out-Null -shutdown /p +wpeutil Shutdown diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 index 509ec57..6d57e45 100644 --- a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 +++ b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 @@ -482,6 +482,9 @@ else{ # Writelog "Failed to extend Windows partition and/or create recovery partition - LastExitCode = $LASTEXITCODE" # } +#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) diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUVM.ps1 b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUVM.ps1 deleted file mode 100644 index 3c74201..0000000 --- a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUVM.ps1 +++ /dev/null @@ -1,544 +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 {$_.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 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 in that 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 -# WriteLog 'Begin Logging' - -#Find PhysicalDrive -$PhysicalDeviceID = Get-HardDrive -# WriteLog "Physical DeviceID is $PhysicalDeviceID" - -#Parse DiskID Number -$DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1,1) -# WriteLog "DiskID is $DiskID" - -#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: $_" - } -} - -#Partition drive -# Writelog 'Creating partitions' -#Start-Process -FilePath diskpart.exe -ArgumentList "/S $UEFIFFUPartitions" -Wait -ErrorAction Stop | Out-File $Logfile -Append -Invoke-Process diskpart.exe "/S $UEFIFFUPartitions" -# Writelog 'Creating partitions succeeded' - -#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 - -#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' -} -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 -} - -#Extend Windows partition and create recovery partition -# Writelog 'Extending Windows partition' -Invoke-Process diskpart.exe "/S $ExtendPartition" -# Writelog 'Extending Windows partition succeeded' - - -#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 ($PrefixToUse){ - 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-Host 'Copying Drivers - dism will pop a window with no progress. This can take a few minutes to complete. 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" - - - - diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU_last.ps1 b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU_last.ps1 deleted file mode 100644 index b93e7bb..0000000 --- a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU_last.ps1 +++ /dev/null @@ -1,579 +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 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 -WriteLog 'Begin Logging' - -#Find PhysicalDrive -$PhysicalDeviceID = Get-HardDrive -WriteLog "Physical DeviceID is $PhysicalDeviceID" - -#Parse DiskID Number -$DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1,1) -WriteLog "DiskID is $DiskID" - -#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' -} -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 - } -} - -#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" -} - -#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 ($PrefixToUse){ - 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" - - - - diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUv2.ps1 b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUv2.ps1 deleted file mode 100644 index 66274de..0000000 --- a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUv2.ps1 +++ /dev/null @@ -1,555 +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 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 in that 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 -WriteLog 'Begin Logging' - -#Find PhysicalDrive -$PhysicalDeviceID = Get-HardDrive -WriteLog "Physical DeviceID is $PhysicalDeviceID" - -#Parse DiskID Number -$DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1,1) -WriteLog "DiskID is $DiskID" - -#Modify diskpart answer files if DiskID not 0 -$UEFIFFUPartitions = 'x:\CreateUEFI-FFU-Partitions.txt' -$ExtendPartition = 'x:\ExtendPartition-UEFI.txt' -$RecoveryPartition = 'x:\RecoveryPartition-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: $_" - } - try { - Set-DiskpartAnswerFiles $RecoveryPartition $DiskID - } - catch { - WriteLog "Modifying $RecoveryPartition failed with error: $_" - } -} - -#Partition drive -Writelog 'Creating partitions' -#Start-Process -FilePath diskpart.exe -ArgumentList "/S $UEFIFFUPartitions" -Wait -ErrorAction Stop | Out-File $Logfile -Append -Invoke-Process diskpart.exe "/S $UEFIFFUPartitions" -Writelog 'Creating partitions succeeded' - -#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 - -#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' -} -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 -} -#Change code to allow for optimized FFUs - -#Extend Windows partition and create recovery partition -# Writelog 'Extending Windows partition' -# Invoke-Process diskpart.exe "/S $ExtendPartition" -# Writelog 'Extending Windows partition succeeded' - - -#Copy modified WinRE if folder exists, else copy inbox WinRE -$WinRE = $USBDrive + "WinRE\winre.wim" -If (Test-Path -Path $WinRE) -{ - WriteLog 'Assigning recovery partition drive letter R' - Invoke-Process diskpart.exe "/S $RecoveryPartition" - WriteLog 'Assigned recovery partition drive letter R successfully' - 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 ($PrefixToUse){ - 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-Host 'Copying Drivers - dism will pop a window with no progress. This can take a few minutes to complete. 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" - - - - diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUv3.ps1 b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUv3.ps1 deleted file mode 100644 index 2b288b5..0000000 --- a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFUv3.ps1 +++ /dev/null @@ -1,554 +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 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 in that 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 -WriteLog 'Begin Logging' - -#Find PhysicalDrive -$PhysicalDeviceID = Get-HardDrive -WriteLog "Physical DeviceID is $PhysicalDeviceID" - -#Parse DiskID Number -$DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1,1) -WriteLog "DiskID is $DiskID" - -#Modify diskpart answer files if DiskID not 0 -$UEFIFFUPartitions = 'x:\CreateUEFI-FFU-Partitions.txt' -$ExtendPartition = 'x:\ExtendPartition-UEFI.txt' -$RecoveryPartition = 'x:\RecoveryPartition-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: $_" - } - try { - Set-DiskpartAnswerFiles $RecoveryPartition $DiskID - } - catch { - WriteLog "Modifying $RecoveryPartition 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 'Creating partitions' -#Start-Process -FilePath diskpart.exe -ArgumentList "/S $UEFIFFUPartitions" -Wait -ErrorAction Stop | Out-File $Logfile -Append -Invoke-Process diskpart.exe "/S $UEFIFFUPartitions" -Writelog 'Creating partitions 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' -} -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 -} -#Change code to allow for optimized FFUs - -#Extend Windows partition and create recovery partition -# Writelog 'Extending Windows partition' -# Invoke-Process diskpart.exe "/S $ExtendPartition" -# Writelog 'Extending Windows partition succeeded' - - -#Copy modified WinRE if folder exists, else copy inbox WinRE -$WinRE = $USBDrive + "WinRE\winre.wim" -If (Test-Path -Path $WinRE) -{ - WriteLog 'Assigning recovery partition drive letter R' - Invoke-Process diskpart.exe "/S $RecoveryPartition" - WriteLog 'Assigned recovery partition drive letter R successfully' - 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 ($PrefixToUse){ - 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-Host 'Copying Drivers - dism will pop a window with no progress. This can take a few minutes to complete. 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" - - - - diff --git a/FFUDevelopment/WinPEDeployFFUFiles/CreateUEFI-FFU-Partitions.txt b/FFUDevelopment/WinPEDeployFFUFiles/CreateUEFI-FFU-Partitions.txt deleted file mode 100644 index 2773059..0000000 --- a/FFUDevelopment/WinPEDeployFFUFiles/CreateUEFI-FFU-Partitions.txt +++ /dev/null @@ -1,3 +0,0 @@ -select disk 0 -clean -exit diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ExtendPartition-UEFI.txt b/FFUDevelopment/WinPEDeployFFUFiles/ExtendPartition-UEFI.txt deleted file mode 100644 index cf2a9ff..0000000 --- a/FFUDevelopment/WinPEDeployFFUFiles/ExtendPartition-UEFI.txt +++ /dev/null @@ -1,11 +0,0 @@ -select disk 0 -select partition 3 -Assign letter="W" -extend -shrink minimum=650 -create partition primary -format quick fs=ntfs label="Recovery" -assign letter="R" -set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac" -gpt attributes=0x8000000000000001 -exit diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ExtendPartition-UEFIold.txt b/FFUDevelopment/WinPEDeployFFUFiles/ExtendPartition-UEFIold.txt deleted file mode 100644 index cf2a9ff..0000000 --- a/FFUDevelopment/WinPEDeployFFUFiles/ExtendPartition-UEFIold.txt +++ /dev/null @@ -1,11 +0,0 @@ -select disk 0 -select partition 3 -Assign letter="W" -extend -shrink minimum=650 -create partition primary -format quick fs=ntfs label="Recovery" -assign letter="R" -set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac" -gpt attributes=0x8000000000000001 -exit diff --git a/FFUDevelopment/unattend/prefixes.txt b/FFUDevelopment/unattend/prefixes.txt new file mode 100644 index 0000000..ff6f6e5 --- /dev/null +++ b/FFUDevelopment/unattend/prefixes.txt @@ -0,0 +1,4 @@ +1234- +5678- +ABCD +WXYZ \ No newline at end of file diff --git a/FFUDevelopment/unattend/unattend.xml b/FFUDevelopment/unattend/unattend.xml new file mode 100644 index 0000000..9ce5316 --- /dev/null +++ b/FFUDevelopment/unattend/unattend.xml @@ -0,0 +1,8 @@ + + + + + MyComputer + + + \ No newline at end of file