Created
August 6, 2020 02:59
-
-
Save abd3lraouf/bb202bdea4e19db0e4c5e4a2f12917ae to your computer and use it in GitHub Desktop.
Create Iso from PS>5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function New-IsoFile | |
{ | |
[CmdletBinding(DefaultParameterSetName='Source')]Param( | |
[parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true, ParameterSetName='Source')]$Source, | |
[parameter(Position=2)][string]$Path = "$env:temp\$((Get-Date).ToString('yyyyMMdd-HHmmss.ffff')).iso", | |
[ValidateScript({Test-Path -LiteralPath $_ -PathType Leaf})][string]$BootFile = $null, | |
[ValidateSet('CDR','CDRW','DVDRAM','DVDPLUSR','DVDPLUSRW','DVDPLUSR_DUALLAYER','DVDDASHR','DVDDASHRW','DVDDASHR_DUALLAYER','DISK','DVDPLUSRW_DUALLAYER','BDR','BDRE')][string] $Media = 'DVDPLUSRW_DUALLAYER', | |
[string]$Title = (Get-Date).ToString("yyyyMMdd-HHmmss.ffff"), | |
[switch]$Force, | |
[parameter(ParameterSetName='Clipboard')][switch]$FromClipboard | |
) | |
Begin { | |
($cp = new-object System.CodeDom.Compiler.CompilerParameters).CompilerOptions = '/unsafe' | |
if (!('ISOFile' -as [type])) { | |
Add-Type -CompilerOptions "/unsafe" -TypeDefinition @' | |
public class ISOFile | |
{ | |
public unsafe static void Create(string Path, object Stream, int BlockSize, int TotalBlocks) | |
{ | |
int bytes = 0; | |
byte[] buf = new byte[BlockSize]; | |
var ptr = (System.IntPtr)(&bytes); | |
var o = System.IO.File.OpenWrite(Path); | |
var i = Stream as System.Runtime.InteropServices.ComTypes.IStream; | |
if (o != null) { | |
while (TotalBlocks-- > 0) { | |
i.Read(buf, BlockSize, ptr); o.Write(buf, 0, bytes); | |
} | |
o.Flush(); o.Close(); | |
} | |
} | |
} | |
'@ | |
} | |
if ($BootFile) { | |
if('BDR','BDRE' -contains $Media) { Write-Warning "Bootable image doesn't seem to work with media type $Media" } | |
($Stream = New-Object -ComObject ADODB.Stream -Property @{Type=1}).Open() # adFileTypeBinary | |
$Stream.LoadFromFile((Get-Item -LiteralPath $BootFile).Fullname) | |
($Boot = New-Object -ComObject IMAPI2FS.BootOptions).AssignBootImage($Stream) | |
} | |
$MediaType = @('UNKNOWN','CDROM','CDR','CDRW','DVDROM','DVDRAM','DVDPLUSR','DVDPLUSRW','DVDPLUSR_DUALLAYER','DVDDASHR','DVDDASHRW','DVDDASHR_DUALLAYER','DISK','DVDPLUSRW_DUALLAYER','HDDVDROM','HDDVDR','HDDVDRAM','BDROM','BDR','BDRE') | |
Write-Verbose -Message "Selected media type is $Media with value $($MediaType.IndexOf($Media))" | |
($Image = New-Object -com IMAPI2FS.MsftFileSystemImage -Property @{VolumeName=$Title}).ChooseImageDefaultsForMediaType($MediaType.IndexOf($Media)) | |
if (!($Target = New-Item -Path $Path -ItemType File -Force:$Force -ErrorAction SilentlyContinue)) { Write-Error -Message "Cannot create file $Path. Use -Force parameter to overwrite if the target file already exists."; break } | |
} | |
Process { | |
if($FromClipboard) { | |
if($PSVersionTable.PSVersion.Major -lt 5) { Write-Error -Message 'The -FromClipboard parameter is only supported on PowerShell v5 or higher'; break } | |
$Source = Get-Clipboard -Format FileDropList | |
} | |
foreach($item in $Source) { | |
if($item -isnot [System.IO.FileInfo] -and $item -isnot [System.IO.DirectoryInfo]) { | |
$item = Get-Item -LiteralPath $item | |
} | |
if($item) { | |
Write-Verbose -Message "Adding item to the target image: $($item.FullName)" | |
try { $Image.Root.AddTree($item.FullName, $true) } catch { Write-Error -Message ($_.Exception.Message.Trim() + ' Try a different media type.') } | |
} | |
} | |
} | |
End { | |
if ($Boot) { $Image.BootImageOptions=$Boot } | |
$Result = $Image.CreateResultImage() | |
[ISOFile]::Create($Target.FullName,$Result.ImageStream,$Result.BlockSize,$Result.TotalBlocks) | |
Write-Verbose -Message "Target image ($($Target.FullName)) has been created" | |
$Target | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment