Author Posts

February 12, 2016 at 9:09 am

This function works when used as a helper function inside a module or when dot sourced into the current session. But does not work when exported from a module

`
function Mount-VhdAndRunBlock
{

param
(
# Path to VHD(x) file
[Parameter(Mandatory=$true)]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[string]
$vhd,

# Script block to execute (Drive letter stored in $driveletter)
[Parameter(Mandatory=$true)]
[scriptblock]
$block,

# Mount the VHD(x) readonly, This is faster. Use when only reading files.
[switch]
$ReadOnly
)

# This function mounts a VHD, runs a script block and unmounts the VHD.
# Drive letter of the mounted VHD is stored in $driveLetter – can be used by script blocks
if($ReadOnly)
{
$virtualDisk = Mount-VHD $vhd -ReadOnly -Passthru
}
else
{
$virtualDisk = Mount-VHD $vhd -Passthru
}
# Workarround for new drive letters in script modules
$null = Get-PSDrive
$driveLetter = ($virtualDisk |
Get-Disk |
Get-Partition |
Get-Volume).DriveLetter
& $block

Dismount-VHD $vhd

# Wait 2 seconds for activity to clean up
Start-Sleep -Seconds 2
}
`

`
Mount-VhdAndRunBlock -vhd $ImagePath -block { $driveLetter } -ReadOnly
`

This should return the drive letter of the vhd's mount point. but I get nothing.

I think this is a scoping issue but I'm lost on how to fix.

February 12, 2016 at 9:46 am

Script blocks are a bit funny; they stay bound to the caller's scope even when they're passed in to a module function as a parameter. Since you're defining $driveLetter in your module function, and the script block parameter is still bound to the caller, it can't resolve the $driveLetter variable.

This design can be a bit of a code smell; depends on what it is you're trying to do with that script block. However, you can create a copy of the script block that isn't bound to any particular scope like this, and invoke that instead:

$newScriptBlock = [scriptblock]::Create($block.ToString())
& $newScriptBlock

February 12, 2016 at 9:54 am

Thanks that worked perfectly. I figured you would know

Where can I find some good references for how scoping works?