mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
revamped automation
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
REM Put each app install on a separate line
|
||||
REM M365 Apps/Office ProPlus
|
||||
d:\Office\setup.exe /configure d:\Office\DeployFFU.xml
|
||||
REM Add additional apps below here
|
||||
REM Contoso App (Example)
|
||||
REM msiexec /i d:\Contoso\setup.msi /qn /norestart
|
||||
REM The below lines will remove the unattend.xml that gets the machine into audit mode. If not removed, the OS will get stuck booting to audit mode each time.
|
||||
REM Also kills the sysprep process in order to automate sysprep generalize
|
||||
del c:\windows\panther\unattend\unattend.xml /F /Q
|
||||
del c:\windows\panther\unattend.xml /F /Q
|
||||
taskkill /IM sysprep.exe
|
||||
timeout /t 5
|
||||
c:\windows\system32\sysprep\sysprep.exe /quiet /generalize /oobe
|
||||
@@ -6,6 +6,8 @@
|
||||
<ExcludeApp ID="Lync" />
|
||||
<ExcludeApp ID="Publisher" />
|
||||
<ExcludeApp ID="Bing" />
|
||||
<ExcludeApp ID="Teams" />
|
||||
<ExcludeApp ID="Outlook" />
|
||||
</Product>
|
||||
</Add>
|
||||
<Property Name="SharedComputerLicensing" Value="0" />
|
||||
@@ -1,5 +1,5 @@
|
||||
<Configuration ID="efa6df21-a106-428e-8eaa-d89a5dda6030">
|
||||
<Add SourcePath = "C:\FFUDevelopment\Office" OfficeClientEdition="64" Channel="MonthlyEnterprise">
|
||||
<Add SourcePath="C:\FFUDevelopment\Apps\Office" OfficeClientEdition="64" Channel="MonthlyEnterprise">
|
||||
<Product ID="O365ProPlusRetail">
|
||||
<Language ID="MatchOS" />
|
||||
<ExcludeApp ID="Access" />
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<unattend xmlns="urn:schemas-microsoft-com:unattend">
|
||||
<settings pass="auditUser">
|
||||
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<RunAsynchronous>
|
||||
<RunAsynchronousCommand wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<Path>d:\InstallAppsandSysprep.cmd</Path>
|
||||
</RunAsynchronousCommand>
|
||||
</RunAsynchronous>
|
||||
</component>
|
||||
</settings>
|
||||
<settings pass="oobeSystem">
|
||||
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Reseal>
|
||||
<Mode>Audit</Mode>
|
||||
</Reseal>
|
||||
</component>
|
||||
</settings>
|
||||
<cpi:offlineImage cpi:source="wim:c:/wimtoffu/win11_22h2_feb2023_consumer.wim#Windows 11 Pro" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
|
||||
</unattend>
|
||||
+1328
-49
File diff suppressed because it is too large
Load Diff
@@ -1,21 +0,0 @@
|
||||
rd c:\FFUDevelopment\WinPE /S /Q
|
||||
cmd /c copype amd64 c:\FFUDevelopment\WinPE
|
||||
Dism /Mount-Image /ImageFile:"c:\FFUDevelopment\WinPE\media\sources\boot.wim" /Index:1 /MountDir:"c:\FFUDevelopment\WinPE\mount"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-WMI.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-WMI_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-NetFX.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-NetFX_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-Scripting.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-Scripting_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-PowerShell.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-PowerShell_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-StorageWMI.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-StorageWMI_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-DismCmdlets.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-DismCmdlets_en-us.cab"
|
||||
xcopy "C:\FFUDevelopment\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:<Path to Drivers folder e.g c:\drivers> /Recurse
|
||||
Dism /Unmount-Image /MountDir:c:\FFUDevelopment\WinPE\mount /Commit
|
||||
MakeWinPEMedia /ISO /F c:\FFUDevelopment\WinPE "c:\FFUDevelopment\WinPE_FFU_Capture.iso"
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
rd c:\FFUDevelopment\WinPE /S /Q
|
||||
cmd /c copype amd64 c:\FFUDevelopment\WinPE
|
||||
Dism /Mount-Image /ImageFile:"c:\FFUDevelopment\WinPE\media\sources\boot.wim" /Index:1 /MountDir:"c:\FFUDevelopment\WinPE\mount"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-WMI.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-WMI_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-NetFX.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-NetFX_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-Scripting.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-Scripting_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-PowerShell.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-PowerShell_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-StorageWMI.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-StorageWMI_en-us.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-DismCmdlets.cab"
|
||||
Dism /Add-Package /Image:"c:\FFUDevelopment\WinPE\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-DismCmdlets_en-us.cab"
|
||||
xcopy "C:\FFUDevelopment\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:<Path to Drivers folder e.g c:\drivers> /Recurse
|
||||
Dism /Unmount-Image /MountDir:c:\FFUDevelopment\WinPE\mount /Commit
|
||||
MakeWinPEMedia /ISO /F c:\FFUDevelopment\WinPE "c:\FFUDevelopment\WinPE_FFU_Deploy.iso"
|
||||
@@ -1,19 +0,0 @@
|
||||
#Modify variables
|
||||
$ISOPath = 'C:\ffu\WinPE_FFU_Capture.iso'
|
||||
|
||||
$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 *intel*
|
||||
get-vm $VMName | Get-VMNetworkAdapter | Connect-VMNetworkAdapter -SwitchName $VMSwitch.Name
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
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"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,21 +0,0 @@
|
||||
#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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<Configuration ID="efa6df21-a106-428e-8eaa-d89a5dda6030">
|
||||
<Add OfficeClientEdition="64" Channel="MonthlyEnterprise">
|
||||
<Product ID="O365ProPlusRetail">
|
||||
<Language ID="MatchOS" />
|
||||
<ExcludeApp ID="Access" />
|
||||
<ExcludeApp ID="Lync" />
|
||||
<ExcludeApp ID="Publisher" />
|
||||
<ExcludeApp ID="Bing" />
|
||||
</Product>
|
||||
</Add>
|
||||
<Property Name="SharedComputerLicensing" Value="0" />
|
||||
<Property Name="FORCEAPPSHUTDOWN" Value="FALSE" />
|
||||
<Property Name="DeviceBasedLicensing" Value="0" />
|
||||
<Property Name="SCLCacheOverride" Value="0" />
|
||||
<Updates Enabled="TRUE" />
|
||||
<Display Level="None" AcceptEULA="TRUE" />
|
||||
</Configuration>
|
||||
@@ -1,4 +0,0 @@
|
||||
d:\setup.exe /configure d:\DeployFFU.xml
|
||||
taskkill /IM sysprep.exe
|
||||
timeout /t 5
|
||||
c:\windows\system32\sysprep\sysprep.exe /quiet /generalize /oobe
|
||||
@@ -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$\FFUDevelopment /user:administrator p@ssw0rd
|
||||
#Modify the net use W: \\192.168.1.158\FFUCaptureShare /user:ffu_user 62bffb7c-4350-426c-8151-58093bb90117
|
||||
net use W: \\192.168.1.158\FFUCaptureShare /user:ffu_user 62bffb7c-4350-426c-8151-58093bb90117
|
||||
|
||||
$AssignDriveLetter = 'x:\AssignDriveLetter.txt'
|
||||
Start-Process -FilePath diskpart.exe -ArgumentList "/S $AssignDriveLetter" -Wait -ErrorAction Stop | Out-Null
|
||||
@@ -14,11 +14,13 @@ $SKU = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersio
|
||||
$DisplayVersion = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'DisplayVersion'
|
||||
$BuildDate = Get-Date -uformat %b%Y
|
||||
|
||||
$SKU = switch ($SKU){
|
||||
Home {'Home'}
|
||||
Professional {'Pro'}
|
||||
ProfessionalEducation {'Pro_Edu'}
|
||||
Enterprise {'Ent'}
|
||||
$SKU = switch ($SKU) {
|
||||
Core { 'Home' }
|
||||
Professional { 'Pro' }
|
||||
ProfessionalEducation { 'Pro_Edu' }
|
||||
Enterprise { 'Ent' }
|
||||
Education { 'Edu' }
|
||||
ProfessionalWorkstation { 'Pro_Wks' }
|
||||
}
|
||||
|
||||
if($CurrentBuild -ge 22000){
|
||||
@@ -30,7 +32,7 @@ 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'
|
||||
$Office = Get-childitem -Path 'M:\Program Files\Microsoft Office' -ErrorAction SilentlyContinue
|
||||
if($Office){
|
||||
$ffuFilePath = "W:\$Name`_$DisplayVersion`_$SKU`_Office`_$BuildDate.ffu"
|
||||
$dismArgs = "/capture-ffu /imagefile=$ffuFilePath /capturedrive=\\.\PhysicalDrive0 /name:$Name$DisplayVersion$SKU /Compress:Default"
|
||||
@@ -38,7 +40,7 @@ if($Office){
|
||||
|
||||
}
|
||||
else{
|
||||
$ffuFilePath = "W:\$Name`_$DisplayVersion`_$SKU`_$BuildDate.ffu"
|
||||
$ffuFilePath = "W:\$Name`_$DisplayVersion`_$SKU`_Apps`_$BuildDate.ffu"
|
||||
$dismArgs = "/capture-ffu /imagefile=$ffuFilePath /capturedrive=\\.\PhysicalDrive0 /name:$Name$DisplayVersion$SKU /Compress:Default"
|
||||
|
||||
}
|
||||
@@ -54,4 +56,7 @@ reg unload "HKLM\FFU"
|
||||
Start-Process -FilePath dism.exe -ArgumentList $dismArgs -Wait -PassThru -ErrorAction Stop | Out-Null
|
||||
#Copy DISM log to Host
|
||||
xcopy X:\Windows\logs\dism\dism.log W:\ /Y | Out-Null
|
||||
|
||||
#Remvove W: drive
|
||||
net use W: \\192.168.1.158\FFUCaptureShare /user:ffu_user 62bffb7c-4350-426c-8151-58093bb90117
|
||||
wpeutil Shutdown
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
1234-
|
||||
5678-
|
||||
ABCD
|
||||
WXYZ
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<unattend xmlns="urn:schemas-microsoft-com:unattend">
|
||||
<settings pass="specialize">
|
||||
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<ComputerName>MyComputer</ComputerName>
|
||||
</component>
|
||||
</settings>
|
||||
</unattend>
|
||||
@@ -1,556 +0,0 @@
|
||||
#Requires -Modules Hyper-V, Storage
|
||||
#Requires -PSEdition Desktop
|
||||
|
||||
<#
|
||||
.NOTES
|
||||
Copyright (c) Microsoft Corporation.
|
||||
Licensed under the MIT License.
|
||||
|
||||
.SYNOPSIS
|
||||
Creates an FFU with proper disk layout given an input WIM
|
||||
|
||||
.DESCRIPTION
|
||||
Creates an FFU with proper disk layout given an input WIM
|
||||
|
||||
.PARAMETER WimPath
|
||||
The path to the WIM to be converted into an FFU
|
||||
|
||||
.PARAMETER WimIndex
|
||||
The index of the image within the WIM to be used
|
||||
|
||||
.PARAMETER FfuPath
|
||||
Output path of the FFU to be created
|
||||
|
||||
.PARAMETER ScratchVhdxPath
|
||||
Output path of the scratch VHDX which will be created as an intermediate-step to the process of creating the FFU.
|
||||
|
||||
.PARAMETER SaveScratchVhdx
|
||||
Keep the scratch VHDX after capturing the FFU. This VHDX can be used to create a VM for testing.
|
||||
|
||||
.PARAMETER SizeBytes
|
||||
Size in bytes of the disk the FFU is to be applied to.
|
||||
With an Optimized FFU, the FFU can then be applied to any disk large enough for the data within the FFU.
|
||||
|
||||
.PARAMETER LogicalSectorSizeBytes
|
||||
Logical sector size to store data within the FFU.
|
||||
This should match the logical sector size of the disks this FFU is applied to.
|
||||
|
||||
.PARAMETER Dynamic
|
||||
Whether the scratch VHDX is to be a dynamically sized file or a fixed file size to match the maximum size of the VHDX.
|
||||
|
||||
.PARAMETER PartitionStyle
|
||||
GPT or MBR partition style for the final disk layout.
|
||||
|
||||
.PARAMETER SkipSystemPartition
|
||||
Skips creating a System partition. Boot files will be placed on the OS partition.
|
||||
|
||||
.PARAMETER SystemPartitionSize
|
||||
If creating a System partition, specifies the size in bytes of that partition.
|
||||
|
||||
.PARAMETER SkipMSRPartition
|
||||
Skips creating an MSR partition.
|
||||
|
||||
.PARAMETER OSPartitionSize
|
||||
Allows the specification of the OS partition size. If left at default, the OS partition will take all available space,
|
||||
minus what is needed by the Recovery partition, if any.
|
||||
If a Data partition is specified, an OS partition size must be specified.
|
||||
|
||||
.PARAMETER AddDataPartition
|
||||
Allows the addition of an extra Data partition, separate from the OS partition.
|
||||
|
||||
.PARAMETER DataPartitionSize
|
||||
Allows specifying the size of the Data partition, if the -AddDataPartition flag is used.
|
||||
|
||||
.PARAMETER SkipRecoveryPartition
|
||||
Skips the creation of a Recovery partition, used to store the Windows Recovery Environment (WinRE.wim).
|
||||
|
||||
.PARAMETER RecoveryPartitionSize
|
||||
Specifies the size of the Recovery partition to be created.
|
||||
If left at default, the partition will be the size of the WinRE.wim in the OS partition plus 52 MB plus a buffer of 32 MB
|
||||
since free space of WinRE.wim + 52 MB is needed.
|
||||
|
||||
.PARAMETER FFUDriveName
|
||||
Name passed to DISM's /Capture-FFU /Name parameter, used to set a name for the FFU, separate from the file name.
|
||||
|
||||
.PARAMETER FFUCompression
|
||||
Specifies FFU compression of Default or None.
|
||||
|
||||
.PARAMETER FirmwareType
|
||||
Specifies to create boot files for the disk for a firmware of BIOS, UEFI, or both (ALL).
|
||||
|
||||
.PARAMETER OptimizeFfu
|
||||
Creates an Optimized FFU which can be applied to a disk of a different size than the original FFU disk size
|
||||
as long as the disk it is applied to is large enough to fit the data within the FFU.
|
||||
Optimized FFUs are only available on Windows version 1903 and higher.
|
||||
|
||||
.PARAMETER Force
|
||||
Forces the overwriting of existing scratch VHDX or FFUs if the script is run multiple times
|
||||
or specifying a path with an existing VHDX or FFU of the same name.
|
||||
|
||||
.EXAMPLE
|
||||
.\Convert-WimToFfu.ps1 -WimPath .\install.wim
|
||||
|
||||
Creates an FFU named install.ffu in the same directory as the passed install.wim
|
||||
|
||||
.EXAMPLE
|
||||
.\Convert-WimToFfu.ps1 -WimPath .\install.wim -WimIndex 1 -FfuPath .\flash.ffu
|
||||
|
||||
Creates an FFU from the Windows image at index 1 within install.wim and names the FFU "flash.ffu"
|
||||
|
||||
.EXAMPLE
|
||||
.\Convert-WimToFfu.ps1 -WimPath .\install.wim -WimIndex 1 -FfuPath .\flash.ffu -SizeBytes 64GB
|
||||
|
||||
Creates an FFU that can only be applied on "64GB" disks.
|
||||
Keep in mind that 64GB is 68,719,476,736 bytes which may be larger than the target disks.
|
||||
|
||||
.EXAMPLE
|
||||
.\Convert-WimToFfu.ps1 -WimPath .\install.wim -WimIndex 1 -FfuPath .\flash.ffu -OptimizeFfu
|
||||
Creates an FFU which can be applied to disks of a different size than the original FFU disk size.
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[Alias("Path")]
|
||||
[ValidateScript({ Test-Path $_ })]
|
||||
[string]$WimPath,
|
||||
[uint32]$WimIndex = 1,
|
||||
[string]$FfuPath,
|
||||
[string]$ScratchVhdxPath,
|
||||
[switch]$SaveScratchVhdx,
|
||||
[uint64]$SizeBytes = 31000000000,
|
||||
[ValidateSet(512, 4096)]
|
||||
[uint32]$LogicalSectorSizeBytes = 512,
|
||||
[switch]$Dynamic,
|
||||
[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Disk.PartitionStyle]$PartitionStyle = [Microsoft.PowerShell.Cmdletization.GeneratedTypes.Disk.PartitionStyle]::GPT,
|
||||
[switch]$SkipSystemPartition,
|
||||
[uint64]$SystemPartitionSize = 256MB,
|
||||
[switch]$SkipMSRPartition,
|
||||
[uint64]$OSPartitionSize = 0,
|
||||
[switch]$AddDataPartition,
|
||||
[uint64]$DataPartitionSize = 0,
|
||||
[switch]$SkipRecoveryPartition,
|
||||
[uint64]$RecoveryPartitionSize = 0,
|
||||
[string]$FFUDriveName = "WimToFfu",
|
||||
[ValidateSet("Default", "None")]
|
||||
[string]$FFUCompression = "Default",
|
||||
[ValidateSet("UEFI", "BIOS", "ALL")]
|
||||
[string]$FirmwareType = "UEFI",
|
||||
[switch]$OptimizeFFU,
|
||||
[switch]$Force
|
||||
);
|
||||
|
||||
#region FUNCTIONS
|
||||
|
||||
function Add-BootFiles
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$OsPartitionDriveLetter,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$SystemPartitionDriveLetter
|
||||
);
|
||||
|
||||
Write-Host "Adding boot files for `"$($OsPartitionDriveLetter):\Windows`" to System partition `"$($SystemPartitionDriveLetter):`"...";
|
||||
|
||||
bcdboot "$($OsPartitionDriveLetter):\Windows" /S "$($SystemPartitionDriveLetter):" /F "$FirmwareType";
|
||||
|
||||
Write-Host "Done.";
|
||||
}
|
||||
|
||||
function Get-RecoveryPartition
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ciminstance]$VhdxDisk,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ciminstance]$OsPartition,
|
||||
[uint64]$RecoveryPartitionSize = 0,
|
||||
[ciminstance]$DataPartition
|
||||
);
|
||||
|
||||
Write-Host "Creating empty Recovery partition (to be filled on first boot automatically)...";
|
||||
|
||||
$calculatedRecoverySize = 0;
|
||||
$recoveryPartition = $null;
|
||||
|
||||
if($RecoveryPartitionSize -gt 0)
|
||||
{
|
||||
$calculatedRecoverySize = $RecoveryPartitionSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
$winReWim = Get-ChildItem "$($OsPartition.DriveLetter):\Windows\System32\Recovery\Winre.wim";
|
||||
|
||||
if(($winReWim -ne $null) -and ($winReWim.Count -eq 1))
|
||||
{
|
||||
# Wim size + 52MB is minimum WinRE partition size.
|
||||
# NTFS and other partitioning size differences account for about 17MB of space that's unavailable.
|
||||
# Adding 32MB as a buffer to ensure there's enough space.
|
||||
$calculatedRecoverySize = $winReWim.Length + 52MB + 32MB;
|
||||
|
||||
Write-Host "Calculated space needed for recovery in bytes: $calculatedRecoverySize";
|
||||
|
||||
if($DataPartition -ne $null)
|
||||
{
|
||||
$DataPartition | Resize-Partition -Size ($DataPartition.Size - $calculatedRecoverySize);
|
||||
Write-Host "Data partition shrunk by $calculatedRecoverySize bytes for Recovery partition.";
|
||||
}
|
||||
else
|
||||
{
|
||||
$OsPartition | Resize-Partition -Size ($OsPartition.Size - $calculatedRecoverySize);
|
||||
Write-Host "OS partition shrunk by $calculatedRecoverySize bytes for Recovery partition.";
|
||||
}
|
||||
|
||||
$recoveryPartition = $VhdxDisk | New-Partition -AssignDriveLetter -UseMaximumSize -GptType "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}" `
|
||||
| Format-Volume -FileSystem NTFS -Confirm:$false -Force -NewFileSystemLabel "WinRE";
|
||||
|
||||
Write-Host "Done. Recovery partition at drive $($recoveryPartition.DriveLetter):";
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "No WinRE.WIM found in the OS partition under \Windows\System32\Recovery.";
|
||||
Write-Host "Skipping creating the Recovery partition.";
|
||||
Write-Host "If a Recovery partition is desired, please re-run the script setting the -RecoveryPartitionSize flag as appropriate."
|
||||
}
|
||||
}
|
||||
|
||||
return $recoveryPartition;
|
||||
}
|
||||
|
||||
function Get-DataPartition
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ciminstance]$VhdxDisk,
|
||||
[uint64]$DataPartitionSize = 0
|
||||
);
|
||||
|
||||
Write-Host "Creating Data partition...";
|
||||
|
||||
$dataPartition = $null;
|
||||
|
||||
if(($OSPartitionSize -ne $null) -and ($OSPartitionSize -gt 0))
|
||||
{
|
||||
if(($DataPartitionSize -ne $null) -and ($DataPartitionSize -gt 0))
|
||||
{
|
||||
$dataPartition = $vhdxDisk | New-Partition -AssignDriveLetter -Size $DataPartitionSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
$dataPartition = $vhdxDisk | New-Partition -AssignDriveLetter -UseMaximumSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "To add a data partition, OS partition size must be set. Skipping adding data partition...";
|
||||
}
|
||||
|
||||
Write-Host "Done. Data partition at drive $($dataPartition.DriveLetter):";
|
||||
|
||||
return $dataPartition;
|
||||
}
|
||||
|
||||
function Get-OSPartition
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ciminstance]$VhdxDisk,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WimPath,
|
||||
[uint32]$WimIndex = 1,
|
||||
[uint64]$OSPartitionSize = 0
|
||||
);
|
||||
|
||||
Write-Host "Creating OS partition...";
|
||||
|
||||
if($OSPartitionSize -gt 0)
|
||||
{
|
||||
$osPartition = $vhdxDisk | New-Partition -AssignDriveLetter -Size $OSPartitionSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
$osPartition = $vhdxDisk | New-Partition -AssignDriveLetter -UseMaximumSize;
|
||||
}
|
||||
|
||||
$formattedOsPartition = $osPartition | Format-Volume -FileSystem NTFS -Confirm:$false -Force -NewFileSystemLabel "Windows";
|
||||
Write-Host "Done. OS partition at drive $($osPartition.DriveLetter):";
|
||||
|
||||
Write-Host "Writing WIM at $WimPath to OS partition at drive $($osPartition.DriveLetter):...";
|
||||
|
||||
#Server 2019 is missing the Windows Overlay Filter (wof.sys), likely other Server SKUs are missing it as well. Script will error if trying to use the -compact switch on Server OSes
|
||||
if((Get-CimInstance Win32_OperatingSystem).Caption -match "Server"){
|
||||
Write-Host (Expand-WindowsImage -ImagePath $WimPath -Index $WimIndex -ApplyPath "$($osPartition.DriveLetter):\");
|
||||
}
|
||||
else {
|
||||
Write-Host (Expand-WindowsImage -ImagePath $WimPath -Index $WimIndex -ApplyPath "$($osPartition.DriveLetter):\" -Compact);
|
||||
}
|
||||
|
||||
Write-Host "Done.";
|
||||
|
||||
return $osPartition;
|
||||
}
|
||||
|
||||
function Get-MSRPartition
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ciminstance]$VhdxDisk
|
||||
);
|
||||
|
||||
Write-Host "Creating MSR partition...";
|
||||
|
||||
$toReturn = $VhdxDisk | New-Partition -AssignDriveLetter -Size 16MB -GptType "{e3c9e316-0b5c-4db8-817d-f92df00215ae}" -IsHidden;
|
||||
|
||||
Write-Host "Done.";
|
||||
|
||||
return $toReturn;
|
||||
}
|
||||
|
||||
function Get-SystemPartition
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ciminstance]$VhdxDisk,
|
||||
[uint64]$SystemPartitionSize = 100MB
|
||||
);
|
||||
|
||||
Write-Host "Creating System partition...";
|
||||
|
||||
$sysPartition = $VhdxDisk | New-Partition -AssignDriveLetter -Size $SystemPartitionSize -GptType "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}" -IsHidden;
|
||||
$formattedSysPartition = $sysPartition | Format-Volume -FileSystem FAT32 -Force -NewFileSystemLabel "System";
|
||||
|
||||
Write-Host "Done. System partition at drive $($sysPartition.DriveLetter):";
|
||||
return $sysPartition.DriveLetter;
|
||||
}
|
||||
|
||||
function Dismount-ScratchVhdx
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$VhdxPath
|
||||
);
|
||||
|
||||
if(Test-Path $VhdxPath)
|
||||
{
|
||||
Write-Host "Dismounting scratch VHDX...";
|
||||
Dismount-VHD -Path $VhdxPath;
|
||||
Write-Host "Done.";
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ScratchVhdx
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$VhdxPath,
|
||||
[uint64]$SizeBytes = 64000000000,
|
||||
[ValidateSet(512, 4096)]
|
||||
[uint32]$LogicalSectorSizeBytes = 512,
|
||||
[switch]$Dynamic,
|
||||
[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Disk.PartitionStyle]$PartitionStyle = [Microsoft.PowerShell.Cmdletization.GeneratedTypes.Disk.PartitionStyle]::GPT,
|
||||
[switch]$AddRecoveryPartition,
|
||||
[uint64]$RecoveryPartitionSize = 0
|
||||
);
|
||||
|
||||
Write-Host "Creating new Scratch VHDX...";
|
||||
|
||||
$newVHDX = New-VHD -Path $VhdxPath -SizeBytes $SizeBytes -LogicalSectorSizeBytes $LogicalSectorSizeBytes -Dynamic:($Dynamic.IsPresent);
|
||||
$toReturn = $newVHDX | Mount-VHD -Passthru | Initialize-Disk -PassThru -PartitionStyle $PartitionStyle;
|
||||
|
||||
Write-Host "Done.";
|
||||
return $toReturn;
|
||||
}
|
||||
|
||||
function Get-OutputFilePath
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WimPath,
|
||||
[string]$OutputFilePath,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$ParamName,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Extension,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[bool]$Force
|
||||
);
|
||||
|
||||
if([string]::IsNullOrEmpty($OutputFilePath))
|
||||
{
|
||||
$OutputFilePath = [System.IO.Path]::ChangeExtension($WimPath, $Extension);
|
||||
}
|
||||
|
||||
if((Test-Path $OutputFilePath) -and (-not $Force))
|
||||
{
|
||||
throw New-Object System.ArgumentException("Unable to overwrite existing file $OutputFilePath without -Force flag.", $ParamName);
|
||||
}
|
||||
|
||||
return $OutputFilePath;
|
||||
}
|
||||
|
||||
function Write-If
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[bool]$Condition,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$MessageIfTrue,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$MessageIfFalse
|
||||
);
|
||||
|
||||
if($Condition)
|
||||
{
|
||||
Write-Host $MessageIfTrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host $MessageIfFalse;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MAIN SCRIPT BODY
|
||||
|
||||
#region PRINT INPUT PARAMETERS
|
||||
Write-Host "Using WIM path: $WimPath.";
|
||||
|
||||
$FfuPath = Get-OutputFilePath -WimPath $WimPath -OutputFilePath $FfuPath -ParamName "FfuPath" -Extension "ffu" -Force $Force.IsPresent;
|
||||
Write-Host "Using FFU path: $FfuPath.";
|
||||
|
||||
$ScratchVhdxPath = Get-OutputFilePath -WimPath $WimPath -OutputFilePath $ScratchVhdxPath -ParamName "ScratchVhdxPath" -Extension "vhdx" -Force $Force.IsPresent;
|
||||
Write-Host "Using VHDX path: $ScratchVhdxPath.";
|
||||
|
||||
Write-Host "Using WIM Index: $WimIndex.";
|
||||
|
||||
Write-If -Condition $SaveScratchVhdx.IsPresent `
|
||||
-MessageIfTrue "Will save intermediate scratch VHDX." `
|
||||
-MessageIfFalse "Will delete intermediate scratch VHDX.";
|
||||
|
||||
Write-Host "Using Disk Size (bytes) of $SizeBytes.";
|
||||
Write-Host "Using Logical Sector Size (bytes) of $LogicalSectorSizeBytes.";
|
||||
|
||||
Write-If -Condition $Dynamic.IsPresent `
|
||||
-MessageIfTrue "Intermediate scratch VHDX on disk will be Dynamically sized." `
|
||||
-MessageIfFalse "Intermediate scratch VHDX on disk will be Fixed sized.";
|
||||
|
||||
Write-Host "Partition style will be $PartitionStyle.";
|
||||
|
||||
Write-If -Condition $SkipSystemPartition.IsPresent `
|
||||
-MessageIfTrue "Will not add System partition." `
|
||||
-MessageIfFalse "Will add System partition of size (bytes) $SystemPartitionSize.";
|
||||
|
||||
Write-If -Condition $SkipMSRPartition.IsPresent `
|
||||
-MessageIfTrue "Will not add MSR partition." `
|
||||
-MessageIfFalse "Will add 16 MB MSR partition.";
|
||||
|
||||
Write-If -Condition ($OSPartitionSize -eq 0) `
|
||||
-MessageIfTrue "Will create maximum-sized OS partition." `
|
||||
-MessageIfFalse "Will create OS partition of size (bytes) $OSPartitionSize.";
|
||||
|
||||
Write-If -Condition $AddDataPartition.IsPresent `
|
||||
-MessageIfTrue "Will add extra Data partition of size (bytes) $DataPartitionSize." `
|
||||
-MessageIfFalse "Will not add extra Data partition.";
|
||||
|
||||
Write-If -Condition $SkipRecoveryPartition.IsPresent `
|
||||
-MessageIfTrue "Will not add Recovery partition." `
|
||||
-MessageIfFalse "Will add Recovery partition.";
|
||||
|
||||
Write-If -Condition $OptimizeFFU.IsPresent `
|
||||
-MessageIfTrue "Will run DISM's /Optimize-FFU command." `
|
||||
-MessageIfFalse "Will skip DISM's /Optimize-FFU command.";
|
||||
|
||||
if(-not ($SkipSystemPartition.IsPresent))
|
||||
{
|
||||
if($RecoveryPartitionSize -eq 0)
|
||||
{
|
||||
Write-Host "Will use default, calculated Recovery partition size (WinRE.WIM size + 52 MB + plus a buffer of 32 MB due to NTFS).";
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "Will add Recovery partition of size (bytes) $RecoveryPartitionSize.";
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Using FFU Drive name of $FFUDriveName.";
|
||||
Write-Host "Using FFU compression of $FFUCompression.";
|
||||
Write-Host "Using Firmware Type (for boot files) of $FirmwareType.";
|
||||
|
||||
Write-If -Condition $Force.IsPresent `
|
||||
-MessageIfTrue "Force flag is present. Overwriting files when necessary." `
|
||||
-MessageIfFalse "Force flag is not present. Will not overwrite existing files.";
|
||||
|
||||
#endregion PRINT INPUT PARAMETERS
|
||||
|
||||
try
|
||||
{
|
||||
$vhdxDisk = Get-ScratchVhdx -VhdxPath $ScratchVhdxPath -SizeBytes $SizeBytes -LogicalSectorSizeBytes $LogicalSectorSizeBytes -Dynamic:($Dynamic.IsPresent) -PartitionStyle $PartitionStyle;
|
||||
|
||||
if(-not ($SkipSystemPartition.IsPresent))
|
||||
{
|
||||
$systemPartitionDriveLetter = Get-SystemPartition -VhdxDisk $vhdxDisk -SystemPartitionSize $SystemPartitionSize;
|
||||
}
|
||||
|
||||
if(-not ($SkipMSRPartition.IsPresent))
|
||||
{
|
||||
$msrPartition = Get-MSRPartition -VhdxDisk $vhdxDisk;
|
||||
}
|
||||
|
||||
$osPartition = Get-OSPartition -VhdxDisk $vhdxDisk -OSPartitionSize $OSPartitionSize -WimPath $WimPath -WimIndex $WimIndex;
|
||||
|
||||
if($AddDataPartition.IsPresent)
|
||||
{
|
||||
$dataPartition = Get-DataPartition -VhdxDisk $vhdxDisk -DataPartitionSize $DataPartitionSize;
|
||||
}
|
||||
|
||||
if(-not($SkipRecoveryPartition.IsPresent))
|
||||
{
|
||||
$recoveryPartition = Get-RecoveryPartition -VhdxDisk $vhdxDisk -OsPartition $osPartition -RecoveryPartitionSize $RecoveryPartitionSize -DataPartition $dataPartition;
|
||||
}
|
||||
|
||||
Write-Host "All necessary partitions created.";
|
||||
|
||||
if($SkipSystemPartition.IsPresent)
|
||||
{
|
||||
Add-BootFiles -OsPartitionDriveLetter $osPartition.DriveLetter -SystemPartitionDriveLetter $osPartition.DriveLetter;
|
||||
}
|
||||
else
|
||||
{
|
||||
Add-BootFiles -OsPartitionDriveLetter $osPartition.DriveLetter -SystemPartitionDriveLetter $systemPartitionDriveLetter;
|
||||
}
|
||||
|
||||
Write-Host "Capturing scratch VHDX into FFU...";
|
||||
dism /Capture-FFU /ImageFile:"$FfuPath" /CaptureDrive:"\\.\PhysicalDrive$($vhdxDisk.DiskNumber)" /Name:"$FFUDriveName" /Compress:"$FFUCompression"
|
||||
Write-Host "Done.";
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dismount-ScratchVhdx -VhdxPath $ScratchVhdxPath;
|
||||
}
|
||||
|
||||
if($SaveScratchVhdx.IsPresent)
|
||||
{
|
||||
Write-Host "Scratch VHDX has been kept at $ScratchVhdxPath";
|
||||
}
|
||||
else
|
||||
{
|
||||
Remove-Item -Path $ScratchVhdxPath -Force -Confirm:$false;
|
||||
Write-Host "Scratch VHDX has been deleted.";
|
||||
}
|
||||
|
||||
if($OptimizeFFU.IsPresent)
|
||||
{
|
||||
Write-Host "Running DISM /Optimize-FFU /ImageFile:$FfuPath...";
|
||||
dism /Optimize-FFU /ImageFile:"$FfuPath"
|
||||
Write-Host "Done.";
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "Skipping running DISM /Optimize-FFU.";
|
||||
}
|
||||
|
||||
Write-Host "Convert-WimToFfu.ps1 script complete.";
|
||||
|
||||
#endregion
|
||||
|
||||
Reference in New Issue
Block a user