Write-IStreamToFile.ps1

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)
}