Enforcing Paired Statements Using ScriptBlock
To be honest I feel this might be overcomplicating things.

I use Push-Location/Pop-Location in try/finally blocks when needed (like when loading the SQLPS module), but that's almost never.

For the most part I think one should avoid changing the current location and instead reference the desired path (either relative or absolute). So something like:

$p = $BasePath | Join-Path -ChildPath 'subfolder'
Get-ChildItem -Path $p


rather than:

$p = $BasePath | Join-Path -ChildPath 'subfolder'
Push-Location $p
try {
    Get-ChildItem
} finally {
    Pop-Location
}


As you've seen, there are also some issues with using scriptblocks in that way. You might have scope issues with variables, and call stack/execution context will be a bit different. This might get complicated further when you consider pipelines.

So in summary I'd rather avoid changing the working directory and then not obfuscate the process when I do so it's clear what's going on.