Functions/Convert-Wim2VHD.ps1
function Convert-Wim2VHD { <# .Synopsis Create a VHDX and populate it from a WIM .DESCRIPTION This command will create a VHD or VHDX formated for UEFI (Gen 2/GPT) or BIOS (Gen 1/MBR) You must supply the path to the VHD/VHDX file and a valid WIM/ISO. You should also include the index number for the Windows Edition to install. .EXAMPLE Convert-WIM2VHDX -Path c:\windows8.vhdx -WimPath d:\Source\install.wim -Recovery -DiskLayout UEFI .EXAMPLE Convert-WIM2VHDX -Path c:\windowsServer.vhdx -WimPath d:\Source\install.wim -index 3 -Size 40GB -force -DiskLayout UEFI #> [CmdletBinding(SupportsShouldProcess = $true, PositionalBinding = $false, ConfirmImpact = 'Medium')] Param ( # Path to the new VHDX file (Must end in .vhdx) [Parameter(Position = 0,Mandatory = $true, HelpMessage = 'Enter the path for the new VHDX file')] [ValidateNotNullorEmpty()] [ValidatePattern(".\.vhdx?$")] [ValidateScript({ if (Get-FullFilePath -Path $_ | Split-Path | Resolve-Path ) { $true } else { Throw "Parent folder for $_ does not exist." } })] [string]$Path, # Size in Bytes (Default 40B) [ValidateRange(25GB,64TB)] [long]$Size = 40GB, # Create Dynamic disk [switch]$Dynamic, # Specifies whether to build the image for BIOS (MBR), UEFI (GPT), or WindowsToGo (MBR). # Generation 1 VMs require BIOS (MBR) images. Generation 2 VMs require UEFI (GPT) images. # Windows To Go images will boot in UEFI or BIOS [Parameter(Mandatory = $true)] [Alias('Layout')] [string] [ValidateNotNullOrEmpty()] [ValidateSet('BIOS', 'UEFI', 'WindowsToGo')] $DiskLayout, # Create the Recovery Environment Tools Partition. Only valid on UEFI layout [switch]$RecoveryTools, # Create the Recovery Environment Tools and Recovery Image Partitions. Only valid on UEFI layout [switch]$RecoveryImage, # Force the overwrite of existing files [switch]$force, # Path to WIM or ISO used to populate VHDX [parameter(Position = 1,Mandatory = $true, HelpMessage = 'Enter the path to the WIM/ISO file')] [ValidateScript({ Test-Path -Path (Get-FullFilePath -Path $_ ) })] [string]$SourcePath, # Index of image inside of WIM (Default 1) [int]$Index = 1, # Path to file to copy inside of VHD(X) as C:\unattent.xml [ValidateScript({ if ($_) { Test-Path -Path $_ } else { $true } })] [string]$Unattend, # Native Boot does not have the boot code inside the VHD(x) it must exist on the physical disk. [switch]$NativeBoot, # Features to turn on (in DISM format) [ValidateNotNullOrEmpty()] [string[]]$Feature, # Feature to remove (in DISM format) [ValidateNotNullOrEmpty()] [string[]]$RemoveFeature, # Feature Source path. If not provided, all ISO and WIM images in $sourcePath searched [ValidateNotNullOrEmpty()] [ValidateScript({ Test-Path -Path $(Resolve-Path $_) })] [string]$FeatureSource, # Feature Source index. If the source is a .wim provide an index Default =1 [int]$FeatureSourceIndex = 1, # Path to drivers to inject [ValidateNotNullOrEmpty()] [ValidateScript({ Test-Path -Path $(Resolve-Path $_) })] [string[]]$Driver, # Add payload for all removed features [switch]$AddPayloadForRemovedFeature, # Path of packages to install via DSIM [ValidateNotNullOrEmpty()] [ValidateScript({ Test-Path -Path $(Resolve-Path $_) })] [string[]]$Package, # Files/Folders to copy to root of Winodws Drive (to place files in directories mimic the direcotry structure off of C:\) [ValidateNotNullOrEmpty()] [ValidateScript({ foreach ($Path in $_) { Test-Path -Path $(Resolve-Path $Path) } })] [string[]]$filesToInject ) $Path = $Path | Get-FullFilePath $SourcePath = $SourcePath | Get-FullFilePath $VhdxFileName = Split-Path -Leaf -Path $Path if ($pscmdlet.ShouldProcess("[$($MyInvocation.MyCommand)] : Overwrite partitions inside [$Path] with content of [$SourcePath]", "Overwrite partitions inside [$Path] with contentce of [$SourcePath]? ", 'Overwrite WARNING!')) { if((-not (Test-Path $Path)) -Or $force -Or $pscmdlet.ShouldContinue('Are you sure? Any existin data will be lost!', 'Warning')) { $ParametersToPass = @{} foreach ($key in ('Whatif', 'Verbose', 'Debug')) { if ($PSBoundParameters.ContainsKey($key)) { $ParametersToPass[$key] = $PSBoundParameters[$key] } } $InitializeVHDPartitionParam = @{ 'Size' = $Size 'Path' = $Path 'force' = $true 'DiskLayout' = $DiskLayout } if ($RecoveryTools) { $InitializeVHDPartitionParam.add('RecoveryTools', $true) } if ($RecoveryImage) { $InitializeVHDPartitionParam.add('RecoveryImage', $true) } if ($Dynamic) { $InitializeVHDPartitionParam.add('Dynamic', $true) } $SetVHDPartitionParam = @{ 'SourcePath' = $SourcePath 'Path' = $Path 'Index' = $Index 'force' = $true 'Confirm' = $false } if ($Unattend) { $SetVHDPartitionParam.add('Unattend', $Unattend) } if ($NativeBoot) { $SetVHDPartitionParam.add('NativeBoot', $NativeBoot) } if ($Feature) { $SetVHDPartitionParam.add('Feature', $Feature) } if ($RemoveFeature) { $SetVHDPartitionParam.add('RemoveFeature', $RemoveFeature) } if ($FeatureSource) { $SetVHDPartitionParam.add('FeatureSource', $FeatureSource) } if ($FeatureSourceIndex) { $SetVHDPartitionParam.add('FeatureSourceIndex', $FeatureSourceIndex) } if ($AddPayloadForRemovedFeature) { $SetVHDPartitionParam.add('AddPayloadForRemovedFeature', $AddPayloadForRemovedFeature) } if ($Driver) { $SetVHDPartitionParam.add('Driver', $Driver) } if ($Package) { $SetVHDPartitionParam.add('Package', $Package) } if ($filesToInject) { $SetVHDPartitionParam.add('filesToInject', $filesToInject) } Write-Verbose -Message "[$($MyInvocation.MyCommand)] : InitializeVHDPartitionParam" Write-Verbose -Message ($InitializeVHDPartitionParam | Out-String) Write-Verbose -Message "[$($MyInvocation.MyCommand)] : SetVHDPartitionParam" Write-Verbose -Message ($SetVHDPartitionParam | Out-String) Write-Verbose -Message "[$($MyInvocation.MyCommand)] : ParametersToPass" Write-Verbose -Message ($ParametersToPass | Out-String) Try { Initialize-VHDPartition @InitializeVHDPartitionParam @ParametersToPass Set-VHDPartition @SetVHDPartitionParam @ParametersToPass } Catch { throw "$($_.Exception.Message) at $($_.Exception.InvocationInfo.ScriptLineNumber)" } } } } |