Private/steps-osd/Step-OSDCloudExpandWindowsImage.ps1
|
function Step-OSDCloudExpandWindowsImage { <# .SYNOPSIS Expands the selected OSDCloud Windows image to the local disk. .DESCRIPTION Creates a temporary scratch directory, builds parameters from the active OSDCloud deployment context, and applies the selected Windows image to C:\. In WinPE, the function runs Expand-WindowsImage, initializes SetupComplete.cmd and OOBE.cmd, removes the source image file after a successful apply, and then removes the scratch directory when the operation completes. .EXAMPLE Step-OSDCloudExpandWindowsImage Expands the image defined by the current OSDCloud deployment globals to C:\. .LINK https://github.com/OSDeploy/OSD/tree/master/docs .NOTES Author: David Segura - Recast Software 2026-07-17 - Added comment-based help block 2026-07-17 - Improved input validation and scratch directory lifecycle handling 2026-07-17 - Remove source image file after successful expansion 2026-09-30 - Initialize Windows setup command files after expansion #> [CmdletBinding()] param () #================================================= Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)]" #================================================= # Validate required OSDCloud deployment context before applying the image. if ($null -eq $global:RecastOSDCloud) { throw "[$(Get-Date -format s)] OSDCloud deployment context was not found." } $ImagePath = $global:RecastOSDCloud.OperatingSystemFileObject.FullName $ImageIndex = $global:RecastOSDCloud.WindowsImageIndex $ScratchDirectory = 'C:\OSDCloud\Temp' if ([string]::IsNullOrWhiteSpace($ImagePath)) { throw "[$(Get-Date -format s)] OSDCloud deployment image path is not set." } if (-not (Test-Path -Path $ImagePath -ErrorAction SilentlyContinue)) { throw "[$(Get-Date -format s)] OSDCloud deployment image path does not exist: $ImagePath" } if (($ImageIndex -as [int]) -lt 1) { throw "[$(Get-Date -format s)] OSDCloud deployment image index is invalid: $ImageIndex" } #================================================= if ($env:SystemDrive -ne 'X:') { # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Skip. Not running in WinPE (X:)" return } #================================================= try { if (-not (Test-Path -Path $ScratchDirectory -ErrorAction SilentlyContinue)) { New-Item -Path $ScratchDirectory -ItemType Directory -Force -ErrorAction Stop | Out-Null } $ExpandWindowsImageParams = @{ ApplyPath = 'C:\' ErrorAction = 'Stop' ImagePath = $ImagePath Index = [int]$ImageIndex ScratchDirectory = $ScratchDirectory } Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Expand WindowsImage to C:\" try { Expand-WindowsImage @ExpandWindowsImageParams | Out-Null Initialize-OSDCloudSetupScripts } catch { throw "[$(Get-Date -format s)] Expand-WindowsImage failed. $_" } if (Test-Path -Path $ImagePath -ErrorAction SilentlyContinue) { Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing source image $ImagePath" try { Remove-Item -Path $ImagePath -Force -ErrorAction Stop | Out-Null } catch { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Unable to remove source image $ImagePath. $_" } } } finally { if (Test-Path -Path $ScratchDirectory -ErrorAction SilentlyContinue) { Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing scratch directory $ScratchDirectory" try { Remove-Item -Path $ScratchDirectory -Force -Recurse -ErrorAction Stop | Out-Null } catch { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Unable to remove scratch directory $ScratchDirectory. $_" } } if (Test-Path -Path 'C:\OSDCloud' -ErrorAction SilentlyContinue) { Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\OSDCloud" try { Remove-Item -Path 'C:\OSDCloud' -Force -Recurse -ErrorAction Stop | Out-Null } catch { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Unable to remove C:\OSDCloud. $_" } } } #================================================= Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] End" #================================================= } |