Mounting ISO-files with Powershell

In windows 10 and Server 2016 you have built in support for mounting ISO-files to a virtual CD/DVD-Drive.

On my HTPC I wanted to crate a simple and functional GUI to mount and unmount ISO-files.
So I wrote a Powershell-script to manage that. It also starts PowerDVD and start to play that drive the ISO-files has been mounted on.

I’t not beautiful, but functional…
$VDrive = New-Object System.Collections.Generic.List[System.Object]
$PDVDPath = "C:\Program Files (x86)\CyberLink\PowerDVD17\PowerDVD.EXE"
$IsoPaths = "D:"#"F:\4k ISOS"
$IsoFiles = ''


#region Functions

# Refreshes the list of virtual drives
Function RefreshVCDList {
    $VDrive.Clear()
    $Drives = Get-Volume
    ForEach ($Vol in $Drives){
        $DLetter = ''
        $DLetter = $Vol.DriveLetter
        IF (Get-DiskImage -DevicePath "\\.\$DLetter`:" -ErrorAction Ignore){
            Write-host $DLetter
            $VDrive.Add($DLetter)
        }
    }
}

# Refresh the list of Iso-files
Function RefreshIsoFiles {
    $Isos = @()
    ForEach($Path in $IsoPaths){
        $Isos += (Get-ChildItem -path $Path -Recurse -Include '*.iso' -File).FullName
    }
    return $Isos
}

# Unmounts all virtual drives
Function UnMountAll {
    RefreshVCDList
    ForEach($vol in $VDrive){
        Write-Host "unmounting "\\.\$vol`:""
        Dismount-DiskImage -DevicePath "\\.\$vol`:" -ErrorAction ignore
    }
}


# Mounts selected iso-file
Function MountImageFile {
    Param(
    [Parameter(Mandatory = $true)]
    [STRING]$ImagePath
    )
    $global:Mounted = ''
    $IsAllreadyMouted = ''
    $IsAllreadyMouted = (Get-DiskImage -ImagePath "$ImagePath").Attached
    $Driveletter = ''
    Write-Host "Info mountstatus:" $IsAllreadyMouted
    IF($IsAllreadyMouted -eq $false){
        Write-Host "mounting $ImagePath"
        $global:Mounted = (Mount-DiskImage -ImagePath "$ImagePath" -PassThru | Get-Volume)
    } ELSEIF ($IsAllreadyMouted -eq $true){
        Write-Host "Image $ImagePath is allready mounted"
        $global:Mounted = (Get-DiskImage -ImagePath "$ImagePath" | Get-Volume)
    }
    [STRING]$Driveletter = $global:Mounted.DriveLetter +":"
    Write-host "Info mountvolume:" $Driveletter
    return $Driveletter
}

Function UpdateISOList {
    #$LstBoxIsos.ResetText()
    $Files = @()
    RefreshVCDList
    $Files = RefreshIsoFiles
    $LstBoxIsos.Items.Clear()
    ForEach($IsoItem in $Files){
        IF ($IsoItem -ne $null){
            $LstBoxIsos.Items.Add($IsoItem)
        }
    }
}

#endregion

#region GUI
Add-Type -AssemblyName System.Windows.Forms
$FrmMain = New-Object system.Windows.Forms.Form
$FrmMain.Text = "Markus ISO-Mounter"
$FrmMain.TopMost = $false
$FrmMain.Width = 1300
$FrmMain.Height = 800
$FrmMain.TopMost = $false
$FrmMain.Add_Resize({
    #Sets size and place of other stuff when main form changes
    $LstBoxIsos.Width = ($FrmMain.Width - 45)
    $LstBoxIsos.Height = ($FrmMain.Height - 200)

    $BtnRefresh.location = new-object system.drawing.point(10,($FrmMain.Height - 130))
    $BtnUnMount.location = new-object system.drawing.point(130,($FrmMain.Height - 130))
    $ChkBoxUnmount.location = new-object system.drawing.point(10,($FrmMain.Height - 160))
    $ChkStartPDVD.location = new-object system.drawing.point(10,($FrmMain.Height - 190))

})

$LstBoxIsos = New-Object system.windows.Forms.ListBox
$LstBoxIsos.Width = 1255
$LstBoxIsos.Height = 600
$LstBoxIsos.Font = "Microsoft Sans Serif,14"
$LstBoxIsos.HorizontalScrollbar = $true
$LstBoxIsos.Add_DoubleClick({
    $File = $LstBoxIsos.SelectedItem
    [STRING]$MountDrive = ''
    IF ($ChkBoxUnmount.Checked){
        Write-Host "unmounting all drives"
        UnMountAll
    }
    Write-Host "mounting" $File
    $MountDrive = (MountImageFile -ImagePath "$File")
    Write-Host "iso mounted on $MountDrive"
    IF ($ChkStartPDVD.Checked){
    TRY{
        Write-Host "Starting PowerDVD with $MountDrive"
        Start-Process -FilePath $PDVDPath -ArgumentList $MountDrive
    }
    CATCH{
        Write-Host "Could not start PowerDVD"
    }
    }
})
$LstBoxIsos.location = new-object system.drawing.point(10,10)
$FrmMain.controls.Add($LstBoxIsos)

$BtnRefresh = New-Object system.windows.Forms.Button
$BtnRefresh.Text = "Refresh iso-files"
$BtnRefresh.Width = 100
$BtnRefresh.Height = 60
$BtnRefresh.location = new-object system.drawing.point(10,670)
$BtnRefresh.Font = "Microsoft Sans Serif,10"
$BtnRefresh.Add_Click({
    $BtnRefresh.BackColor = "RED"
    $BtnRefresh.Update()
    UpdateISOList
    $BtnRefresh.ResetBackColor()
})
$FrmMain.controls.Add($BtnRefresh)


$BtnUnMount = New-Object system.windows.Forms.Button
$BtnUnMount.Text = "Unmount all drives"
$BtnUnMount.Width = 150
$BtnUnMount.Height = 60
$BtnUnMount.location = new-object system.drawing.point(130,670)
$BtnUnMount.Font = "Microsoft Sans Serif,10"
$BtnUnMount.Add_Click({
    $BtnUnMount.BackColor = "RED"
    $BtnUnMount.Update()
    UnMountAll
    $BtnUnMount.ResetBackColor()
})
$FrmMain.controls.Add($BtnUnMount)

$ChkBoxUnmount = New-Object system.windows.Forms.CheckBox
$ChkBoxUnmount.Text = "Unmount all drives when mouting iso"
$ChkBoxUnmount.AutoSize = $true
$ChkBoxUnmount.Width = 95
$ChkBoxUnmount.Height = 20
$ChkBoxUnmount.location = new-object system.drawing.point(10,640)
$ChkBoxUnmount.Font = "Microsoft Sans Serif,10"
$ChkBoxUnmount.Checked = $true
$FrmMain.controls.Add($ChkBoxUnmount)

$ChkStartPDVD = New-Object system.windows.Forms.CheckBox
$ChkStartPDVD.Text = "Start PowerDVD When mounting iso"
$ChkStartPDVD.AutoSize = $true
$ChkStartPDVD.Width = 95
$ChkStartPDVD.Height = 20
$ChkStartPDVD.location = new-object system.drawing.point(10,610)
$ChkStartPDVD.Font = "Microsoft Sans Serif,10"
$ChkStartPDVD.Checked = $true
$FrmMain.controls.Add($ChkStartPDVD)

#UpdateISOList
[void]$FrmMain.ShowDialog()
$FrmMain.Dispose()

#endregion

If you know better ways in Powershell to mount/unmount and get a list of virtual drives, please let me know. Always fun to make the code better!!