From 7faa384220aa8623eeedf64e46860ced8c24b866 Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Fri, 19 May 2023 18:42:42 +0000 Subject: [PATCH 01/10] Started adding Split and SplitSize parameters. --- Public/New-OSDBuilderUSB.ps1 | 38 +++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/Public/New-OSDBuilderUSB.ps1 b/Public/New-OSDBuilderUSB.ps1 index 9293ba5..be85efe 100644 --- a/Public/New-OSDBuilderUSB.ps1 +++ b/Public/New-OSDBuilderUSB.ps1 @@ -13,6 +13,13 @@ Full Path of the OSDBuilder Media .PARAMETER USBLabel Label for the USB Drive + +.PARAMETER Split +Split install.wim into multiple .swm files. This will be automatically set to $true if the file is reported to be over 4GB. + +.PARAMETER SplitSize +The desired size of the .swm files created when using the "Split" parameter. Note: The integer value should be in MB (ie. 4000 is 4GB) + #> function New-OSDBuilderUSB { [CmdletBinding()] @@ -21,9 +28,34 @@ function New-OSDBuilderUSB { [string]$FullName, [ValidateLength(1,11)] - [string]$USBLabel + [string]$USBLabel, + + [Parameter] + [Switch]$Split ) + dynamicparam + { + if ($Split -eq $true) + { + $parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ + ParameterSetName = "__AllParameterSets" + Mandatory = $true + } + + $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() + $attributeCollection.Add($parameterAttribute) + + $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( + 'SplitSize', [Int32], $attributeCollection + ) + + $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() + $paramDictionary.Add('SplitSize', $dynParam1) + return $paramDictionary + } + } + Begin { #================================================= # Get-OSDBuilder @@ -47,6 +79,8 @@ function New-OSDBuilderUSB { $AllMyOSDBMedia = @() $AllMyOSDBMedia = [array]$AllMyOSMedia + [array]$AllMyOSBuilds + [array]$AllMyPEBuilds + + # TODO: Create variable with size of the install.wim } Process { @@ -56,6 +90,8 @@ function New-OSDBuilderUSB { Write-Warning "USB will be formatted FAT32" Write-Warning "Install.wim larger than 4GB will FAIL" + # TODO: Create a check if install.wim is greater than 4GB or the "split" parameter is selected, then split the wim file into multiple .swm files of the desired size (4GB exactly, if not using the split and splitsize parameters). + #================================================= Write-Verbose '19.1.14 Select Source OSMedia' #================================================= From 87a7c64ec3eb21415e17af6adb76b09c5e2a6593 Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Fri, 19 May 2023 18:49:46 +0000 Subject: [PATCH 02/10] Added a dism example in the comments --- Public/New-OSDBuilderUSB.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Public/New-OSDBuilderUSB.ps1 b/Public/New-OSDBuilderUSB.ps1 index be85efe..f61a7b1 100644 --- a/Public/New-OSDBuilderUSB.ps1 +++ b/Public/New-OSDBuilderUSB.ps1 @@ -91,6 +91,7 @@ function New-OSDBuilderUSB { Write-Warning "Install.wim larger than 4GB will FAIL" # TODO: Create a check if install.wim is greater than 4GB or the "split" parameter is selected, then split the wim file into multiple .swm files of the desired size (4GB exactly, if not using the split and splitsize parameters). + # Example: Dism /Split-Image /ImageFile:C:\install.wim /SWMFile:C:\images\split\install.swm /FileSize:4000 #================================================= Write-Verbose '19.1.14 Select Source OSMedia' From 396251f6bbf0b61b760a4031639f8cc3d39c378b Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Fri, 19 May 2023 20:54:47 +0000 Subject: [PATCH 03/10] Finsihed --- Public/New-OSDBuilderUSB.ps1 | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Public/New-OSDBuilderUSB.ps1 b/Public/New-OSDBuilderUSB.ps1 index f61a7b1..252af4a 100644 --- a/Public/New-OSDBuilderUSB.ps1 +++ b/Public/New-OSDBuilderUSB.ps1 @@ -80,7 +80,6 @@ function New-OSDBuilderUSB { $AllMyOSDBMedia = @() $AllMyOSDBMedia = [array]$AllMyOSMedia + [array]$AllMyOSBuilds + [array]$AllMyPEBuilds - # TODO: Create variable with size of the install.wim } Process { @@ -107,6 +106,18 @@ function New-OSDBuilderUSB { $SelectedOSMedia = $AllMyOSDBMedia | Out-GridView -Title "OSDBuilder: Select one OSMedia to create an USB and press OK (Cancel to Exit)" -OutputMode Single } + Switch ($Split){ + $true { + $SplitSize = 4000 + } + $false { + Continue + } + } + + $WIMSize = (Get-Item "$($SelectedOSMedia.FullName)\OS\Sources\install.wim").Length/1000000 # Returns size in MB + + #================================================= Write-Verbose '19.1.1 Select USB Drive' #================================================= @@ -124,8 +135,14 @@ function New-OSDBuilderUSB { bootsect.exe /nt60 "$($Results.DriveLetter):" #Copy Files from ISO to USB - Copy-Item -Path "$($SelectedOSMedia.FullName)\OS\*" -Destination "$($Results.DriveLetter):" -Recurse -Verbose + if ($Split -eq $true -or $WIMSize -gt 4000){ + Dism /Split-Image /ImageFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.wim" /SWMFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.swm" /FileSize:$SplitSize /Verbose + Copy-Item -Path "$($SelectedOSMedia.FullName)\OS\*" -Destination "$($Results.DriveLetter):" -Recurse -Exclude "$($SelectedOSMedia.FullName)\OS\Sources\install.wim" -Verbose + } else { + Copy-Item -Path "$($SelectedOSMedia.FullName)\OS\*" -Destination "$($Results.DriveLetter):" -Recurse -Verbose + } } + } End { From 6b349fc654b76b398f205c22c42f50db80d863e7 Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Fri, 19 May 2023 21:01:46 +0000 Subject: [PATCH 04/10] Finished logic for split parameter --- Public/New-OSDBuilderUSB.ps1 | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Public/New-OSDBuilderUSB.ps1 b/Public/New-OSDBuilderUSB.ps1 index 252af4a..ea172bd 100644 --- a/Public/New-OSDBuilderUSB.ps1 +++ b/Public/New-OSDBuilderUSB.ps1 @@ -89,9 +89,6 @@ function New-OSDBuilderUSB { Write-Warning "USB will be formatted FAT32" Write-Warning "Install.wim larger than 4GB will FAIL" - # TODO: Create a check if install.wim is greater than 4GB or the "split" parameter is selected, then split the wim file into multiple .swm files of the desired size (4GB exactly, if not using the split and splitsize parameters). - # Example: Dism /Split-Image /ImageFile:C:\install.wim /SWMFile:C:\images\split\install.swm /FileSize:4000 - #================================================= Write-Verbose '19.1.14 Select Source OSMedia' #================================================= @@ -106,18 +103,15 @@ function New-OSDBuilderUSB { $SelectedOSMedia = $AllMyOSDBMedia | Out-GridView -Title "OSDBuilder: Select one OSMedia to create an USB and press OK (Cancel to Exit)" -OutputMode Single } + # Get install.wim size in MB + $WIMSize = (Get-Item "$($SelectedOSMedia.FullName)\OS\Sources\install.wim").Length/1000000 + + # If the split parameter is not selected and install.wim is larger than 4000MB, set the split size to 4000MB Switch ($Split){ - $true { - $SplitSize = 4000 - } - $false { - Continue - } + $true { Continue } + $false { if ( $WIMSize -gt 4000 ) { $SplitSize = 4000 } } } - $WIMSize = (Get-Item "$($SelectedOSMedia.FullName)\OS\Sources\install.wim").Length/1000000 # Returns size in MB - - #================================================= Write-Verbose '19.1.1 Select USB Drive' #================================================= @@ -134,7 +128,7 @@ function New-OSDBuilderUSB { Set-Location -Path "$($SelectedOSMedia.FullName)\OS\boot" bootsect.exe /nt60 "$($Results.DriveLetter):" - #Copy Files from ISO to USB + #Copy Files from ISO to USB and split the install.wim if needed or if specified by the split parameter if ($Split -eq $true -or $WIMSize -gt 4000){ Dism /Split-Image /ImageFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.wim" /SWMFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.swm" /FileSize:$SplitSize /Verbose Copy-Item -Path "$($SelectedOSMedia.FullName)\OS\*" -Destination "$($Results.DriveLetter):" -Recurse -Exclude "$($SelectedOSMedia.FullName)\OS\Sources\install.wim" -Verbose From cde25ab2ea4a5bfc3e50249097a7d0a13cf27186 Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:14:45 +0000 Subject: [PATCH 05/10] Fixed and validated Split parameter and SplitSize dynamic parameter. --- Public/New-OSDBuilderUSB.ps1 | 64 +++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/Public/New-OSDBuilderUSB.ps1 b/Public/New-OSDBuilderUSB.ps1 index ea172bd..ff2205c 100644 --- a/Public/New-OSDBuilderUSB.ps1 +++ b/Public/New-OSDBuilderUSB.ps1 @@ -18,7 +18,7 @@ Label for the USB Drive Split install.wim into multiple .swm files. This will be automatically set to $true if the file is reported to be over 4GB. .PARAMETER SplitSize -The desired size of the .swm files created when using the "Split" parameter. Note: The integer value should be in MB (ie. 4000 is 4GB) +Dynamic parameter when "Split" is used. The desired size of the .swm files created when using the "Split" parameter. Note: The integer value should be in MB (ie. 4000 is 4GB) #> function New-OSDBuilderUSB { @@ -34,27 +34,28 @@ function New-OSDBuilderUSB { [Switch]$Split ) - dynamicparam - { - if ($Split -eq $true) - { - $parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ - ParameterSetName = "__AllParameterSets" - Mandatory = $true - } - - $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() - $attributeCollection.Add($parameterAttribute) - - $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( - 'SplitSize', [Int32], $attributeCollection - ) - - $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() - $paramDictionary.Add('SplitSize', $dynParam1) - return $paramDictionary - } - } + dynamicparam { + if ($Split) { + $ParameterName = "SplitSize" + + $parameterAttribute = New-Object System.Management.Automation.ParameterAttribute + $parameterAttribute.HelpMessage = "Please enter the size you wish to split:" + $parameterAttribute.Mandatory = $true + + $validateAttribute = New-Object System.Management.Automation.ValidateNotNullOrEmptyAttribute + $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() + $attributeCollection.Add($parameterAttribute) + $attributeCollection.Add($validateAttribute) + + $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( + $ParameterName, [Int32], $attributeCollection + ) + + $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() + $paramDictionary.Add( $ParameterName, $dynParam1) + return $paramDictionary + } + } Begin { #================================================= @@ -103,15 +104,6 @@ function New-OSDBuilderUSB { $SelectedOSMedia = $AllMyOSDBMedia | Out-GridView -Title "OSDBuilder: Select one OSMedia to create an USB and press OK (Cancel to Exit)" -OutputMode Single } - # Get install.wim size in MB - $WIMSize = (Get-Item "$($SelectedOSMedia.FullName)\OS\Sources\install.wim").Length/1000000 - - # If the split parameter is not selected and install.wim is larger than 4000MB, set the split size to 4000MB - Switch ($Split){ - $true { Continue } - $false { if ( $WIMSize -gt 4000 ) { $SplitSize = 4000 } } - } - #================================================= Write-Verbose '19.1.1 Select USB Drive' #================================================= @@ -120,6 +112,15 @@ function New-OSDBuilderUSB { } $Results = Get-Disk | Where-Object {$_.Size/1GB -lt 33 -and $_.BusType -eq 'USB'} | Out-GridView -Title 'OSDBuilder: Select a USB Drive to FORMAT' -OutputMode Single | Clear-Disk -RemoveData -RemoveOEM -Confirm:$false -PassThru | New-Partition -UseMaximumSize -IsActive -AssignDriveLetter | Format-Volume -FileSystem FAT32 -NewFileSystemLabel $USBLabel + # Get install.wim size in MB + $WIMSize = (Get-Item "$($SelectedOSMedia.FullName)\OS\Sources\install.wim").Length/100000 + + # If the split parameter is not selected and install.wim is larger than 4000MB, set the split size to 4000MB + Switch ($Split){ + $true { Continue } + $false { if ( $WIMSize -gt 4000 ) { $SplitSize = 4000 } } + } + if ($null -eq $Results) { Write-Warning "No USB Drive was Found or Selected" Return @@ -130,6 +131,7 @@ function New-OSDBuilderUSB { #Copy Files from ISO to USB and split the install.wim if needed or if specified by the split parameter if ($Split -eq $true -or $WIMSize -gt 4000){ + #Create .swm files from the install.wim and copy them over instead of the install.wim (keeps filesize down for FAT32) Dism /Split-Image /ImageFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.wim" /SWMFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.swm" /FileSize:$SplitSize /Verbose Copy-Item -Path "$($SelectedOSMedia.FullName)\OS\*" -Destination "$($Results.DriveLetter):" -Recurse -Exclude "$($SelectedOSMedia.FullName)\OS\Sources\install.wim" -Verbose } else { From 0ede921a4cf19bd130ee5eb06b50c10ad344c840 Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Mon, 5 Jun 2023 12:29:16 -0600 Subject: [PATCH 06/10] Switched the destination for where the .swm files are created. They now go directly to the USB, so as not affect system storage. --- Public/New-OSDBuilderUSB.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Public/New-OSDBuilderUSB.ps1 b/Public/New-OSDBuilderUSB.ps1 index ff2205c..6b59884 100644 --- a/Public/New-OSDBuilderUSB.ps1 +++ b/Public/New-OSDBuilderUSB.ps1 @@ -132,7 +132,7 @@ function New-OSDBuilderUSB { #Copy Files from ISO to USB and split the install.wim if needed or if specified by the split parameter if ($Split -eq $true -or $WIMSize -gt 4000){ #Create .swm files from the install.wim and copy them over instead of the install.wim (keeps filesize down for FAT32) - Dism /Split-Image /ImageFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.wim" /SWMFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.swm" /FileSize:$SplitSize /Verbose + Dism /Split-Image /ImageFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.wim" /SWMFile:"$($Results.DriveLetter):\Sources\install.swm" /FileSize:$SplitSize /Verbose Copy-Item -Path "$($SelectedOSMedia.FullName)\OS\*" -Destination "$($Results.DriveLetter):" -Recurse -Exclude "$($SelectedOSMedia.FullName)\OS\Sources\install.wim" -Verbose } else { Copy-Item -Path "$($SelectedOSMedia.FullName)\OS\*" -Destination "$($Results.DriveLetter):" -Recurse -Verbose From 685201d9f7e24cb51ec918f037ed1818f4a3e5d8 Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Mon, 5 Jun 2023 12:33:28 -0600 Subject: [PATCH 07/10] Updated warning message for install.wim greater than 4GB. --- Public/New-OSDBuilderUSB.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Public/New-OSDBuilderUSB.ps1 b/Public/New-OSDBuilderUSB.ps1 index 6b59884..27f7a38 100644 --- a/Public/New-OSDBuilderUSB.ps1 +++ b/Public/New-OSDBuilderUSB.ps1 @@ -88,7 +88,7 @@ function New-OSDBuilderUSB { Write-Host -ForegroundColor Green "$($MyInvocation.MyCommand.Name) PROCESS" Write-Warning "USB will be formatted FAT32" - Write-Warning "Install.wim larger than 4GB will FAIL" + Write-Warning "Install.wim larger than 4GB will be split into swm files, if the Split parameter is not already specified" #================================================= Write-Verbose '19.1.14 Select Source OSMedia' From 5cbafd49e871d7f0a70597072bce2d5ebca36365 Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Mon, 5 Jun 2023 13:07:03 -0600 Subject: [PATCH 08/10] DISM's "/SWMFile" parameter does not create the "Sources" directory if it doesn't exist, so I had to add it with New-Item before running dism. --- Public/New-OSDBuilderUSB.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Public/New-OSDBuilderUSB.ps1 b/Public/New-OSDBuilderUSB.ps1 index 27f7a38..afd1add 100644 --- a/Public/New-OSDBuilderUSB.ps1 +++ b/Public/New-OSDBuilderUSB.ps1 @@ -132,6 +132,7 @@ function New-OSDBuilderUSB { #Copy Files from ISO to USB and split the install.wim if needed or if specified by the split parameter if ($Split -eq $true -or $WIMSize -gt 4000){ #Create .swm files from the install.wim and copy them over instead of the install.wim (keeps filesize down for FAT32) + New-Item -Path "$($Results.DriveLetter):\" -Name "Sources" -ItemType Directory -Force -Verbose Dism /Split-Image /ImageFile:"$($SelectedOSMedia.FullName)\OS\Sources\install.wim" /SWMFile:"$($Results.DriveLetter):\Sources\install.swm" /FileSize:$SplitSize /Verbose Copy-Item -Path "$($SelectedOSMedia.FullName)\OS\*" -Destination "$($Results.DriveLetter):" -Recurse -Exclude "$($SelectedOSMedia.FullName)\OS\Sources\install.wim" -Verbose } else { From 54ebc6a559ade536de1cf6b04739f3159621401a Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Tue, 12 Sep 2023 22:19:55 -0600 Subject: [PATCH 09/10] Added a quick solution to inject a provisioning package into a mounted wim directory. --- Public/New-OSBuild.ps1 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Public/New-OSBuild.ps1 b/Public/New-OSBuild.ps1 index 59e478d..16cf95b 100644 --- a/Public/New-OSBuild.ps1 +++ b/Public/New-OSBuild.ps1 @@ -88,9 +88,14 @@ function New-OSBuild { # -IncludeKB '4577010','4577015' [string[]]$IncludeKB, + [Alias('PPKG','ProvisioningPackage')] + [ValidatePattern(".*?\.ppkg$")] + [ValidateScript({Test-Path $_})] + [string]$PPKGPath, + #Pauses the function the Install.wim is dismounted #Useful for Testing - [Alias('PauseOS','PauseDismount')] + [switch]$PauseDismountOS = $global:SetOSDBuilder.NewOSBuildPauseDismountOS, #Pauses the function before WinPE is dismounted @@ -960,6 +965,7 @@ function New-OSBuild { #================================================= Add-ContentPack -PackType OSCapability Add-ContentPack -PackType OSPackages + DISM.exe /Image:$MountDirectory /Add-ProvisioningPackage /PackagePath:$PPKGPath Add-WindowsPackageOS Add-FeaturesOnDemandOS #================================================= From bc761ee6be5c9253fc006fd43fe587ff426f43b9 Mon Sep 17 00:00:00 2001 From: Dakota Lewis <85767340+TitanDeploy@users.noreply.github.com> Date: Wed, 13 Sep 2023 11:55:56 -0600 Subject: [PATCH 10/10] Added if statement so that the package injection doesn't run unless a $PPKGPath is provided. --- Public/New-OSBuild.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Public/New-OSBuild.ps1 b/Public/New-OSBuild.ps1 index 16cf95b..dd89231 100644 --- a/Public/New-OSBuild.ps1 +++ b/Public/New-OSBuild.ps1 @@ -965,7 +965,10 @@ function New-OSBuild { #================================================= Add-ContentPack -PackType OSCapability Add-ContentPack -PackType OSPackages - DISM.exe /Image:$MountDirectory /Add-ProvisioningPackage /PackagePath:$PPKGPath + if ($null -ne $PPKGPath){ + Write-Host -ForegroundColor Yellow "Adding $PPKGPath to $MountDirectory" + & DISM.exe /Image:$MountDirectory /Add-ProvisioningPackage /PackagePath:$PPKGPath + } Add-WindowsPackageOS Add-FeaturesOnDemandOS #=================================================