PowerShell 技能连载 - Creating ISO Files

PowerShell 可以将普通文件夹转换为 ISO 文件。ISO 文件是二进制文件,可以被挂载并像只读 CD-ROM 驱动器一样运行。

过去,ISO 文件常用于挂载安装媒体。今天,您可以轻松地创建自己的 ISO 文件,并从自己的文件夹和文件中创建。这样,您可以创建一个简单的备份系统或者方便地与同事共享项目。由于 ISO 文件只是一个单独的文件,因此它们可以很容易地共享,并且由于 Windows 通过双击来挂载它们,并在 Windows Explorer 中显示它们作为 CD-ROM 驱动器,所以您可以立即使用数据而无需提取或解压任何内容。

与 VHD 映像文件相比,挂载 ISO 文件不需要管理员权限。任何人都可以挂载和使用 ISO 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
function New-IsoFile
{
param
(
# path to local folder to store in
# new ISO file (must exist)
[Parameter(Mandatory)]
[String]
$SourceFilePath,

# name of new ISO image (arbitrary,
# turns later into drive label)
[String]
$ImageName = 'MyCDROM',

# path to ISO file to be created
[Parameter(Mandatory)]
[String]
$NewIsoFilePath,

# if specified, the source base folder is
# included into the image file
[switch]
$IncludeRoot
)

# use this COM object to create the ISO file:
$fsi = New-Object -ComObject IMAPI2FS.MsftFileSystemImage

# use this helper object to write a COM stream to a file:
# compile the helper code using these parameters:
$cp = [CodeDom.Compiler.CompilerParameters]::new()
$cp.CompilerOptions = '/unsafe'
$cp.WarningLevel = 4
$cp.TreatWarningsAsErrors = $true
$code = '
using System;
using System.IO;
using System.Runtime.InteropServices.ComTypes;

namespace CustomConverter
{
public static class Helper
{
// writes a stream that came from COM to a filesystem file
public static void WriteStreamToFile(object stream, string filePath)
{
// open output stream to new file
IStream inputStream = stream as IStream;
FileStream outputFileStream = File.OpenWrite(filePath);
int bytesRead = 0;
byte[] data;

// read stream in chunks of 2048 bytes and write to filesystem stream:
do
{
data = Read(inputStream, 2048, out bytesRead);
outputFileStream.Write(data, 0, bytesRead);
} while (bytesRead == 2048);

outputFileStream.Flush();
outputFileStream.Close();
}

// read bytes from stream:
unsafe static private byte[] Read(IStream stream, int byteCount, out int readCount)
{
// create a new buffer to hold the read bytes:
byte[] buffer = new byte[byteCount];
// provide a pointer to the location where the actually read bytes are reported:
int bytesRead = 0;
int* ptr = &bytesRead;
// do the read:
stream.Read(buffer, byteCount, (IntPtr)ptr);
// return the read bytes by reference to the caller:
readCount = bytesRead;
// return the read bytes to the caller:
return buffer;
}
}
}'

Add-Type -CompilerParameters $cp -TypeDefinition $code

# define the ISO file properties:

# create CDROM, Joliet and UDF file systems
$fsi.FileSystemsToCreate = 7
$fsi.VolumeName = $ImageName
# allow larger-than-CRRom-Sizes
$fsi.FreeMediaBlocks = -1

$msg = 'Creating ISO File - this can take a couple of minutes.'
Write-Host $msg -ForegroundColor Green

# define folder structure to be written to image:
$fsi.Root.AddTreeWithNamedStreams($SourceFilePath,$IncludeRoot.IsPresent)

# create image and provide a stream to read it:
$resultimage = $fsi.CreateResultImage()
$resultStream = $resultimage.ImageStream

# write stream to file
[CustomConverter.Helper]::WriteStreamToFile($resultStream, $NewIsoFilePath)

Write-Host 'DONE.' -ForegroundColor Green

}

一旦你运行了这段代码,你现在就有了一个名为 “New-IsoFile” 的新命令。从现有文件夹结构创建 ISO 文件现在变得非常简单 - 只需确保源文件路径存在即可:

1
PS> New-IsoFile -NewIsoFilePath $env:temp\MyTest.iso -ImageName Holiday -SourceFilePath 'C:\HolidayPics'  

您将在临时文件夹中获得一个新的 ISO 文件(或者您指定的任何其他文件路径)。如果您按照示例操作,只需打开临时文件夹即可:

1
PS> explorer /select,$env:temp\MyTest.iso

当您在 Windows 资源管理器中双击 ISO 文件时,该映像将作为新的 CD-ROM 驱动器挂载,并且您可以立即看到存储在图像文件中的数据副本。

右键单击 Windows 资源管理器中的新 CD-ROM 驱动器并从上下文菜单中选择“弹出”将卸载该驱动器。

PowerShell 技能连载 - Creating ISO Files

http://blog.vichamp.com/2023/05/21/creating-iso-files/

作者

吴波

发布于

2023-05-21

更新于

2023-05-22

许可协议

评论