Create ISO of Cumulative Update with PowerShell – Create the ISO
This is the last step in turning your download of a Cumulative Update (CU) into an ISO file. In this part, we want to be able to copy a certain folder on your drive to a new ISO file.
I had no idea how to start with this .. and what do you do when you have no clue? You goo.. sorry .. You BING it (I admit, I googled … ;-))! And here are some resources that really put me in the right direction:
- http://blogs.msdn.com/b/opticalstorage/archive/2010/08/13/writing-optical-discs-using-imapi-2-in-powershell.aspx. This one explained on how to move a folder to an imagestream. I used the first 3 steps of this one, which was actially the point where I should be able to write an ImageStream to disk. The latter appeared not that simple.. .
- https://gist.github.com/marnix/3944688: After some searching, I found exactly what I was looking for: a PowerShell function “WriteIStreamToFile”. Appartenly, this is not really possible in PowerShell, because we can’t use “System.Runtime.InteropServices.ComTypes.Istream. There is more information in the link. You’ll see it’s quite funky: writing C# code in powershell, adding a type which we will be able to use then in PowerShell. I just use this function as-is!
So, the main function is called “New-ISOFileFromFolder” and this is how it looks:
Function New-ISOFileFromFolder{
param(
[Parameter(Mandatory=$true)]
[String]$FilePath,
[Parameter(Mandatory=$true)]
[String]$Name,
[Parameter(Mandatory=$true)]
[String]$ResultFullFileName
)
$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 = 500000 #default 332800
$fsi.Root.AddTreeWithNamedStreams($FilePath,$false)
$resultimage = $fsi.CreateResultImage()
$resultStream = $resultimage.ImageStream
Write-IStreamToFile $resultStream $ResultFullFileName
}You see that I use the resources from above: adding a folder to an image, and having an ImageStream as result. This imagestream is going to be converted to a file with the exact downloaded function from above “Write-IStreamToFile“, which looks like this:
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)
}And there you go, last step is finished! And we have all components we need to convert our exe, our exact download of partnersource of a Cumulative Update, and turn it into an ISO file.
This was originally posted here.

Like
Report
*This post is locked for comments