An easy to use advanced function that will remaster (create) bootable Windows ISO files. The only required parameter is the media path which is the location of the Windows installation media content that will be remastered into an ISO. This allows for easy pipeline processing by simply typing "Path to Media" | New-ISO A PS Custom Object is then returned upon the creation of the ISO that displays the ISO Name, the ISO Label, the path the ISO was saved to, and a Boolean value signifying whether the ISO prompts the user during boot-up or not. Code: Function New-ISO { <# .SYNOPSIS Create a new remastered bootable Windows Installation Media ISO. .DESCRIPTION This function remasters and creates bootable Windows Installation Media ISO files automatically without having to input the paths to the Windows ADK boot files. It does this by querying the registry keys that contain the path the Windows ADK is saved to, and then creating absolute paths to any required boot files for ISO creation. .PARAMETER MediaPath The full path to the Windows media content to be remastered into a new ISO. .PARAMETER SavePath An optional full path to the location where the new remastered ISO is to be saved. .PARAMETER ISOName An optional name of the new ISO file. If no name is supplied, the media name will be used. .PARAMETER ISOLabel An optional label for the new ISO file. .PARAMETER BootType Will create an ISO that prompts for user input upon boot-up, or an ISO that starts automatically with no user prompt. The default setting is no user prompt .EXAMPLE PS C:\> New-ISO -MediaPath "D:\WIN_10_PRO_WORKSTATIONS_17763.194" -SavePath "D:\" -ISOName "Win 10 Pro for Workstations" -ISOLabel "Windows 10 Pro for Workstations" PS C:\> New-ISO -MediaPath "D:\WIN_10_PRO_WORKSTATIONS_17763.194" -BootType "Prompt" PS C:\> "D:\WIN_10_PRO_WORKSTATIONS_17763.194" | New-ISO .NOTES Accepts pipe-line arguments for the media path for quick ISO remastering. The default save location is the user's temporary directory (%TEMP% or $Env:TEMP). #> [CmdletBinding()] [OutputType([PSCustomObject])] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 1, HelpMessage = 'The full path to the Windows media content to be remastered into a new ISO.')] [ValidateScript( { Test-Path $(Resolve-Path -Path $_) })] [string]$MediaPath, [Parameter(Mandatory = $false, HelpMessage = 'The full path to the location where the new remastered ISO is to be saved.')] [string]$SavePath = "$Env:TEMP\$((Get-Date).ToString('MMddyyyy-HHmmss')).iso", [Parameter(Mandatory = $false, HelpMessage = 'An optional name for the new ISO file.')] [ValidateNotNullOrEmpty()] [string]$ISOName = (Get-Date).ToString("MM.dd.yyyy-HHmmss"), [Parameter(Mandatory = $false, HelpMessage = 'An optional label for the new ISO File.')] [string]$ISOLabel = (Get-Date).ToString("MM.dd.yyyy-HHmmss"), [Parameter(HelpMessage = 'Determines whether the ISO requires a key-press during boot-up or not.')] [ValidateSet('Prompt', 'No-prompt')] [string]$BootType = "No-Prompt" ) Begin { @("HKLM:\Software\Wow6432Node\Microsoft\Windows Kits\Installed Roots", "HKLM:\Software\Microsoft\Windows Kits\Installed Roots") | ForEach { If (Test-Path -Path $($_)) { $ADK_ROOT = Get-ItemProperty -Path $($_) -Name KitsRoot10 -ErrorAction SilentlyContinue | Select -ExpandProperty KitsRoot10 | Where { $($_) } } } $DEPLOYMENT_TOOLS = Join-Path -Path $ADK_ROOT -ChildPath ("Assessment and Deployment Kit" + '\' + "Deployment Tools") $OSCDIMG = Join-Path -Path $DEPLOYMENT_TOOLS -ChildPath ($Env:PROCESSOR_ARCHITECTURE + '\' + "Oscdimg") } Process { $BootFiles = (Get-ChildItem -Path $OSCDIMG -ErrorAction SilentlyContinue) If ($ISOName.EndsWith('.iso')) { $ISOName = $ISOName.Replace(' ', '_') } Else { $ISOName = $ISOName.Replace(' ', '') + '.iso' } If ($SavePath.EndsWith('.iso')) { $ISOName = [System.IO.Path]::GetFileNameWithoutExtension($SavePath).Replace(' ', '_') + '.iso'; $SavePath = Split-Path -Path $SavePath -Parent } $ISODest = Join-Path -Path $SavePath -ChildPath $ISOName Switch ($BootType) { 'Prompt' { $BootCode = "efisys.bin"; $BootPrompt = $true } 'No-Prompt' { $BootCode = "efisys_noprompt.bin"; $BootPrompt = $false } } If ((Test-Path -Path "$MediaPath\boot\etfsboot.com") -and (Test-Path -Path "$MediaPath\efi\Microsoft\boot\$BootCode")) { $BootData = '2#p0,e,b"{0}"#pEF,e,b"{1}"' -f "$MediaPath\boot\etfsboot.com", "$MediaPath\efi\Microsoft\boot\$BootCode" } ElseIf ($BootFiles.Name.Contains('etfsboot.com') -and $BootFiles.Name.Contains($BootCode)) { $BootData = '2#p0,e,b"{0}"#pEF,e,b"{1}"' -f "$OSCDIMG\etfsboot.com", "$OSCDIMG\$BootCode" } Else { Write-Warning "Missing required boot files."; Break } If ($ISOLabel) { $OscdimgArgs = @("-bootdata:${BootData}", "-u2", "-udfver102", "-l`"${ISOLabel}`"", "`"${MediaPath}`"", "`"${ISODest}`"") } Else { $OscdimgArgs = @("-bootdata:${BootData}", "-u2", "-udfver102", "`"${MediaPath}`"", "`"${ISODest}`"") } Try { Write-Host "Creating a Bootable ISO..." -NoNewline -ForegroundColor Cyan $Run = Start-Process -FilePath "$OSCDIMG\oscdimg.exe" -ArgumentList $OscdimgArgs -WindowStyle Hidden -Wait Write-Host "[Complete]" -ForegroundColor Cyan } Catch { $Run = "Failed to create $($ISOName), Error $($_)" Write-Warning $Run Break } } End { If ($?) { [PSCustomObject]@{ "ISO Name" = $ISOName "ISO Label" = $ISOLabel "Save Path" = $SavePath "Boot Prompt" = $BootPrompt } | Format-List } } }