In my last post, I talked about mounting disk images in Windows 8. Both Windows 8 and 2012 include native support for mounting ISO images as drives. However, in prior versions of Windows you needed a third party tool to do this. Since I have a preference for open source, my tool of choice before Windows 8 was WinCdEmu. Today, I decided to see if it was possible to determine the drive letter of an ISO mounted by WinCdEMu with PowerShell.
A quick search of the internet revealed that WinCdEmu contained a 32 bit command line tool called batchmnt.exe, and a 64 bit counterpart called batchmnt64.exe. These tools were meant for command line automation. While I knew there would be no .NET libraries in WinCdEmu, I did have hope there would be a COM object I could use with New-Object. Unfortunately, all the COM objects were for Windows Explorer integration and popped up GUIs, so they were inappropriate for automation.
Next I needed to figure out how to use batchmnt. For this I used batchmnt64 /?.
C:\Users\Justin>"C:\Program Files (x86)\WinCDEmu\batchmnt64.exe" /? BATCHMNT.EXE - WinCDEmu batch mounter. Usage: batchmnt <image file> [<drive letter>] [/wait] - mount image file batchmnt /unmount <image file> - unmount image file batchmnt /unmount <drive letter>: - unmount image file batchmnt /check <image file>; - return drive letter as ERORLEVEL batchmnt /unmountall - unmount all images batchmnt /list - list mounted C:\Users\Justin>
Mounting and unmounting are trivial. The /list switch produces some output that I could parse into a PSObject if I so desired. However, what I really found interesting was batchmnt /check. The process returned the drive letter as ERORLEVEL. That means the ExitCode of the batchmnt process. If you ever programmed in a C like language, you know your main function can return an integer. Traditionally 0 means success and a number means failure. However, in this case 0 means the image is not mounted, and a non zero number is the ASCII code of the drive letter. To get that code in PowerShell is simple:
$proc = Start-Process -Wait ` "C:\Program Files (x86)\WinCDEmu\batchmnt64.exe" ` -ArgumentList '/check', '"C:\Users\Justin\SQL Server Media\2008R2\en_sql_server_2008_r2_developer_x86_x64_ia64_dvd_522665.iso"' ` -PassThru; [char] $proc.ExitCode
The Start-Process cmdlet normally returns immediately without output. The -PassThru switch makes it return information about the process it created, and -Wait make the cmdlet wait for the process to exit, so that information includes the exit code. Finally to turn that ASCII code to the drive letter we cast with [char].