コンテンツへスキップ

【Windows 10、11】PowerShell でフォルダからISO ファイルを作成する。New-ISOFile の代用。

Windows でフリーソフトなどを使わずに、「ISO ファイル」を「フォルダから」作成したい。

Linux の場合は、genisoimage などのツール、macOS の場合は、hdiutil などのツールを使用します。
あの、Windows 10 はどうしたらいい?

→ISO ファイルの作成方法はこちら

Windows 10、11 のPowerShell でフォルダからISO ファイルを作成する。New-ISOFile の代用。

Windows の標準機能 でISO ファイルを作成したい。

最初はフリーソフトを検討していたのですが、いざダウンロードしようとすると、
広告 >広告 >ひっかけダウンロード広告 みたいな感じで怖い。

2回ほどマルウェアチェック完全スキャンをかけたところで、標準機能で探してみようと思いました。 

ググったところ、以前はMicrosoft | Docs のサンプルコードギャラリーで「New-IsoFile」というPowerShell のファンクションが公開されていたようですが、現在はなくなってしまっているようで見当たりませんでした。

https://docs.microsoft.com/ja-jp/samples/browse/?redirectedfrom=TechNet-Gallery

しつこくググっていくと、GitHub や、ブログでファンクションのコードを公開しているページをいくつか見つけることができました。

でも、ちょっとなぁ、と思ってさらにしつこくググったところ、
PowerShell Gallery で目的のコードを発見することができました。

https://www.powershellgallery.com/

この安心感。^^
コミュニティなんで、MS 公式ってわけではないですが。。。
やっぱりね。

PowerShell ギャラリー

New-ISOFileFromFolder

↓ これ

New-ISOFileFromFolder.ps1

Write-IStreamToFile

↓ さらに書き込み時に呼び出しているファンクションも。

Write-IStreamToFile.ps1

ISO ファイルを作成する手順。

  1. PowerShell を開く。
  2. 上記2つのファンクションをPowerShell へ「コピぺ」して読み込ませる。
  3. コマンドを実行してISO ファイルを生成する。

※ターゲットはこのフォルダの中身丸ごとです。

※ファイルが2つ入っています。(ぶっちゃけ、AmazonLinux2 の起動ディスクを作ろうとしているところです。)

PowerShell を開く

普通に開きます。管理者とかではないですし、ワーキングディレクトリも多分、どこでもいいです。

PowerShell ギャラリーからコードをコピーして貼り付ける。 

前述のPowerShell ギャラリーから下記の様な感じで、ファンクションを2つ ウィンドウ内にペーストします。

function Write-IStreamToFile([__ComObject] $istream, [string] $fileName)
{
    # NOTE: We cannot use [System.Runtime.InteropServices.ComTypes.IStream],
    # since PowerShell apparently cannot convert an IStream COM object to this
    # Powershell type. (See http://stackoverflow.com/a/9037299/223837 for
    # details.)
    # It turns out that .NET/CLR _can_ do this conversion.
    #
    # That is the reason why method FileUtil.WriteIStreamToFile(), below,
    # takes an object, and casts it to an IStream, instead of directly
    # taking an IStream inputStream argument.

 
    $cp = New-Object CodeDom.Compiler.CompilerParameters             
    $cp.CompilerOptions = "/unsafe"
    $cp.WarningLevel = 4
    $cp.TreatWarningsAsErrors = $true

    Add-Type -CompilerParameters $cp -TypeDefinition @"
        using System;
        using System.IO;
        using System.Runtime.InteropServices.ComTypes;
 
        namespace My
        {
            public static class FileUtil {
                public static void WriteIStreamToFile(object i, string fileName) {
                    IStream inputStream = i as IStream;
                    FileStream outputFileStream = File.OpenWrite(fileName);
                    int bytesRead = 0;
                    int offset = 0;
                    byte[] data;
                    do {
                        data = Read(inputStream, 2048, out bytesRead);
                        outputFileStream.Write(data, 0, bytesRead);
                        offset += bytesRead;
                    } while (bytesRead == 2048);
                    outputFileStream.Flush();
                    outputFileStream.Close();
                }
 
                unsafe static private byte[] Read(IStream stream, int toRead, out int read) {
                    byte[] buffer = new byte[toRead];
                    int bytesRead = 0;
                    int* ptr = &bytesRead;
                    stream.Read(buffer, toRead, (IntPtr)ptr);
                    read = bytesRead;
                    return buffer;
                }
            }
 
        }
"@
 
    [My.FileUtil]::WriteIStreamToFile($istream, $fileName)
}
 
Function New-ISOFileFromFolder{
    <#
        .SYNOPSIS
        Creates an ISO file from a filepath
    #>
    param(
        [Parameter(Mandatory=$true)]
        [String]$FilePath,
        [Parameter(Mandatory=$true)]
        [String]$Name,
        [Parameter(Mandatory=$true)]
        [String]$ResultFullFileName
    )
    write-host "Creating ISO $Name" -ForegroundColor Green  

    $fsi = New-Object -ComObject IMAPI2FS.MsftFileSystemImage
    $dftd = New-Object -ComObject IMAPI2.MsftDiscFormat2Data
    $Recorder = New-Object -ComObject IMAPI2.MsftDiscRecorder2

    $fsi.FileSystemsToCreate = 7
    $fsi.VolumeName = $Name
    $fsi.FreeMediaBlocks = 1000000  #default 332800

    
    $fsi.Root.AddTreeWithNamedStreams($FilePath,$false)


    
    $resultimage = $fsi.CreateResultImage()
    $resultStream = $resultimage.ImageStream


    Write-IStreamToFile $resultStream $ResultFullFileName
    
    
}

貼り付けしたら、エンターキーを押します。

「Get-Command New-ISOFileFromFolder」を実行して下記の様に表示されたらOK です。
ファンクションが使用できる状態です。

ファンクションをコピペで読み込ませて、一時的に読み込んでいる感じですね。

コマンドを実行して、ISO ファイルを生成します。

フォーマット:

New-ISOFileFromFolder <ターゲットのフォルダパス> <ISO のタイトル> <ISO ファイル名をフルパスで指定>
※引数の間は半角の空白で区切ります。

下記の様なメッセージがかえってきたらOK です。

指定したフォルダを確認します。

マウントして、ちゃんとISO イメージとして使えるか確認。
ちゃんとマウントされていました。

編集後記的な。

今回、Aamazon Linux2 の起動ディスク作成をWindows で完結したくて調べてみたのですが、
AmazonLinux2 で使用するためには、Rock Ridge(ロックリッジ)に対応している必要があるようで、ISO ファイルは生成できたものの、そのあとの作業はうまくできませんでした。orz

オプティカルディスクのフォーマットについて

あと、Linux(CentOS)で作成したファイルサイズと比べると、3倍くらい大きいですね。

以上です。

(Visited 73 times, 3 visits today)
タグ:

コメントを残す

メールアドレスが公開されることはありません。