Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
130 lines (112 sloc) 5.8 KB
$ISOScriptsFolder = ".\configuration\iso-scripts\"
$ISOFolder = ".\answer-iso\"
function New-IsoFile
# Script originally authored by Chris Wu
# Borrowed from:
Creates a new .iso file
The New-IsoFile cmdlet creates a new .iso file containing content from chosen folders
New-IsoFile "c:\tools","c:Downloads\utils"
This command creates a .iso file in $env:temp folder (default location) that contains c:\tools and c:\downloads\utils folders. The folders themselves are included at the root of the .iso image.
New-IsoFile -FromClipboard -Verbose
Before running this command, select and copy (Ctrl-C) files/folders in Explorer first.
dir c:\WinPE | New-IsoFile -Path c:\temp\WinPE.iso -BootFile "${env:ProgramFiles(x86)}\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\efisys.bin" -Media DVDPLUSR -Title "WinPE"
This command creates a bootable .iso file containing the content from c:\WinPE folder, but the folder itself isn't included. Boot file can be found in Windows ADK. Refer to IMAPI_MEDIA_PHYSICAL_TYPE enumeration for possible media types:
NAME: New-IsoFile
AUTHOR: Chris Wu
LASTEDIT: 03/23/2016 14:46:50
[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,
[string]$Title = (Get-Date).ToString("yyyyMMdd-HHmmss.ffff"),
Begin {
($cp = new-object System.CodeDom.Compiler.CompilerParameters).CompilerOptions = '/unsafe'
if (!('ISOFile' -as [type])) {
Add-Type -CompilerParameters $cp -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)
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()
Write-Verbose -Message "Target image ($($Target.FullName)) has been created"
# Remove ISOFolder if it already exists.
if (Test-Path $ISOFolder)
Remove-Item $ISOFolder -Force -Recurse | Out-Null
# Create a new ISOFolder.
New-Item $ISOFolder -Type Directory -Force | Out-Null
# Delete answer.iso if it already exists.
if (Test-Path "$ISOScriptsFolder\answer.iso")
Remove-Item "$ISOScriptsFolder\answer.iso" -Force | Out-Null
# Move all of our files to the ISOFolder so they'll be wrapped up in an ISO file.
Copy-Item $ISOScriptsFolder\* -Destination $ISOFolder -Force | Out-Null
# Create a new ISO file called answer.iso from the files in the ISOFolder.
Get-ChildItem $ISOFolder | New-IsoFile -Path $ISOScriptsFolder\answer.iso -Force
# Cleanup the ISO Folder.
if (Test-Path $ISOFolder)
Remove-Item $ISOFolder -Recurse -Force | Out-Null