Create ISO of Cumulative Update with PowerShell – Create the ISO

052115_1446_CreateISOof1.pngThis 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.

0.00 avg. rating (0% score) - 0 votes

Permanent link to this article: https://www.waldo.be/2015/05/27/create-iso-of-cumulative-update-with-powershell-create-the-iso/

2 comments

2 pings

    • adam vonPtak on August 18, 2015 at 6:24 pm
    • Reply

    How do I make the iso bootable?

      • waldo on October 30, 2015 at 4:17 pm
        Author

      I really don’t know – but there is tons of information on the internet… sorry ..

  1. […] Bron : Waldo’s Blog Lees meer… […]

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.